Skip to content

Commit

Permalink
feat: Stub out variant conversion for JNI for now
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Sep 23, 2024
1 parent 5aeb4d9 commit 3359e17
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 4 deletions.
39 changes: 39 additions & 0 deletions packages/nitrogen/src/syntax/kotlin/KotlinCxxBridgedType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { PromiseType } from '../types/PromiseType.js'
import { RecordType } from '../types/RecordType.js'
import { StructType } from '../types/StructType.js'
import type { Type } from '../types/Type.js'
import { VariantType } from '../types/VariantType.js'
import { getKotlinBoxedPrimitiveType } from './KotlinBoxedPrimitive.js'
import { createKotlinEnum } from './KotlinEnum.js'
import { createKotlinFunction } from './KotlinFunction.js'
Expand Down Expand Up @@ -89,6 +90,13 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
space: 'system',
})
break
case 'variant':
imports.push({
language: 'c++',
name: 'NitroModules/JVariant.hpp',
space: 'system',
})
break
case 'hybrid-object': {
const hybridObjectType = getTypeAs(this.type, HybridObjectType)
const name = getHybridObjectName(hybridObjectType.hybridObjectName)
Expand Down Expand Up @@ -265,6 +273,19 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
default:
return this.type.getCode(language)
}
case 'variant': {
switch (language) {
case 'c++':
const variant = getTypeAs(this.type, VariantType)
const variants = variant.variants.map((v) => {
const bridge = new KotlinCxxBridgedType(v)
return bridge.getTypeCode('c++', true)
})
return `JVariant${variant.variants.length}<${variants.join(', ')}>`
default:
return this.type.getCode(language)
}
}
case 'promise':
switch (language) {
case 'c++':
Expand Down Expand Up @@ -356,6 +377,16 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
return parameterName
}
}
case 'variant': {
switch (language) {
case 'c++':
return `[=]() -> ${this.asJniReferenceType('alias')} { throw std::runtime_error("Cannot convert C++ variant to Kotlin/JNI variant yet!"); }()`
// const variant = getTypeAs(this.type, VariantType)
// return `JVariant${variant.variants.length}::create(${parameterName})`
default:
return parameterName
}
}
case 'enum': {
switch (language) {
case 'c++':
Expand Down Expand Up @@ -518,6 +549,14 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
return parameterName
}
}
case 'variant': {
switch (language) {
case 'c++':
return `[=]() -> ${this.type.getCode('c++')} { throw std::runtime_error("Cannot convert Kotlin variant to C++ variant yet!"); }()`
default:
return parameterName
}
}
case 'hybrid-object': {
switch (language) {
case 'c++':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace NitroModules { class ArrayBuffer; }
#include <string>
#include <optional>
#include <variant>
#include <NitroModules/JVariant.hpp>
#include <memory>
#include "HybridTestObjectSwiftKotlinSpec.hpp"
#include "JHybridTestObjectSwiftKotlinSpec.hpp"
Expand Down Expand Up @@ -125,13 +126,13 @@ namespace margelo::nitro::image {
method(_javaPart, optionalString.has_value() ? jni::make_jstring(optionalString.value()) : nullptr);
}
std::variant<std::string, double> JHybridTestObjectSwiftKotlinSpec::getSomeVariantFirst() {
static const auto method = _javaPart->getClass()->getMethod<jni::local_ref<std::variant<std::string, double>>()>("getSomeVariantFirst");
static const auto method = _javaPart->getClass()->getMethod<jni::local_ref<JVariant2<jni::JString, jni::JDouble>>()>("getSomeVariantFirst");
auto result = method(_javaPart);
return result;
return [=]() -> std::variant<std::string, double> { throw std::runtime_error("Cannot convert Kotlin variant to C++ variant yet!"); }();
}
void JHybridTestObjectSwiftKotlinSpec::setSomeVariantFirst(const std::variant<std::string, double>& someVariantFirst) {
static const auto method = _javaPart->getClass()->getMethod<void(jni::alias_ref<std::variant<std::string, double>> /* someVariantFirst */)>("setSomeVariantFirst");
method(_javaPart, someVariantFirst);
static const auto method = _javaPart->getClass()->getMethod<void(jni::alias_ref<JVariant2<jni::JString, jni::JDouble>> /* someVariantFirst */)>("setSomeVariantFirst");
method(_javaPart, [=]() -> jni::alias_ref<JVariant2<jni::JString, jni::JDouble>> { throw std::runtime_error("Cannot convert C++ variant to Kotlin/JNI variant yet!"); }());
}
std::shared_ptr<margelo::nitro::image::HybridTestObjectSwiftKotlinSpec> JHybridTestObjectSwiftKotlinSpec::getThisObject() {
static const auto method = _javaPart->getClass()->getMethod<jni::local_ref<JHybridTestObjectSwiftKotlinSpec::javaobject>()>("getThisObject");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// JVariant.hpp
// react-native-nitro
//
// Created by Marc Rousavy on 14.07.24.
//

#pragma once

#include <fbjni/fbjni.h>

namespace margelo::nitro {

using namespace facebook;

template <typename A, typename B>
class JVariant2 : public jni::JavaClass<JVariant2<A, B>> {
public:
static constexpr auto kJavaDescriptor = "Lcom/example/Variant2;"; // Adjust the descriptor to your package.
};
template <typename A>
class JVariant2_First : public JVariant2<A, jobject> {
public:
static constexpr auto kJavaDescriptor = "Lcom/example/Variant2$First;";

static jni::local_ref<JVariant2_First<A>> create(A value) {
return JVariant2_First<A>::newInstance(value);
}

A getValue() {
static const auto method = JVariant2_First<A>::javaClassStatic()->getMethod<A()>("getValue");
return method(this->self());
}
};
template <typename B>
class JVariant2_Second : public JVariant2<jobject, B> {
public:
static constexpr auto kJavaDescriptor = "Lcom/example/Variant2$Second;";

static jni::local_ref<JVariant2_Second<B>> create(B value) {
return JVariant2_Second<B>::newInstance(value);
}

B getValue() {
static const auto method = JVariant2_Second<B>::javaClassStatic()->getMethod<B()>("getValue");
return method(this->self());
}
};

template <typename T>
T getAs(jobject variant) {
static const auto method = jni::findClassStatic("com/example/Variant2")
->getMethod<jni::local_ref<jobject>()>("getAs");
auto result = method(variant);
return jni::dynamic_ref_cast<T>(result);
}

} // namespace margelo::nitro

0 comments on commit 3359e17

Please sign in to comment.