Summary:
This fixes an issue in the C++ TurboModule codegen where optional return types would result in a compiler error because they were not being defaulted to `null` when converting to `jsi::Value`.

Changelog:
Internal

Reviewed By: javache

Differential Revision: D36989312

fbshipit-source-id: 525f9ce7a5638ba5a655fa69ba9647978030ab0b
This commit is contained in:
Scott Kyle 2022-06-08 21:15:53 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 47bd78f64f
Коммит 68e4e91bd4
4 изменённых файлов: 57 добавлений и 12 удалений

Просмотреть файл

@ -50,6 +50,27 @@ T callFromJs(
rt, fromJs<Args>(rt, std::forward<JSArgs>(args), jsInvoker)...),
jsInvoker);
} else if constexpr (is_optional_v<T>) {
static_assert(
is_optional_v<R>
? supportsToJs<typename R::value_type, typename T::value_type>
: supportsToJs<R, typename T::value_type>,
"Incompatible return type");
auto result = toJs(
rt,
(instance->*method)(
rt, fromJs<Args>(rt, std::forward<JSArgs>(args), jsInvoker)...),
jsInvoker);
if constexpr (std::is_same_v<decltype(result), jsi::Value>) {
if (result.isNull() || result.isUndefined()) {
return std::nullopt;
}
}
return convert(rt, std::move(result));
} else {
static_assert(std::is_convertible_v<R, T>, "Incompatible return type");

Просмотреть файл

@ -24,6 +24,15 @@ inline constexpr bool is_jsi_v =
std::is_same_v<jsi::String, remove_cvref_t<T>> ||
std::is_base_of_v<jsi::Object, remove_cvref_t<T>>;
template <typename>
struct is_optional : std::false_type {};
template <typename T>
struct is_optional<std::optional<T>> : std::true_type {};
template <typename T>
inline constexpr bool is_optional_v = is_optional<T>::value;
template <typename T>
struct Converter;

Просмотреть файл

@ -17,6 +17,7 @@ import type {
NativeModulePropertyShape,
NativeModuleFunctionTypeAnnotation,
NativeModuleParamTypeAnnotation,
NativeModuleTypeAnnotation,
} from '../../CodegenSchema';
import type {AliasResolver} from './Utils';
@ -28,21 +29,33 @@ type FilesOutput = Map<string, string>;
const HostFunctionTemplate = ({
hasteModuleName,
methodName,
isVoid,
returnTypeAnnotation,
args,
}: $ReadOnly<{
hasteModuleName: string,
methodName: string,
isVoid: boolean,
returnTypeAnnotation: Nullable<NativeModuleTypeAnnotation>,
args: Array<string>,
}>) => {
const isNullable = returnTypeAnnotation.type === 'NullableTypeAnnotation';
const isVoid = returnTypeAnnotation.type === 'VoidTypeAnnotation';
const methodCallArgs = ['rt', ...args].join(', ');
const methodCall = `static_cast<${hasteModuleName}CxxSpecJSI *>(&turboModule)->${methodName}(${methodCallArgs});`;
const methodCall = `static_cast<${hasteModuleName}CxxSpecJSI *>(&turboModule)->${methodName}(${methodCallArgs})`;
return `static jsi::Value __hostFunction_${hasteModuleName}CxxSpecJSI_${methodName}(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {${
isVoid ? `\n ${methodCall}` : ''
isVoid
? `\n ${methodCall};`
: isNullable
? `\n auto result = ${methodCall};`
: ''
}
return ${isVoid ? 'jsi::Value::undefined();' : methodCall}
return ${
isVoid
? 'jsi::Value::undefined()'
: isNullable
? 'result ? jsi::Value(std::move(*result)) : jsi::Value::null()'
: methodCall
};
}`;
};
@ -173,13 +186,11 @@ function serializePropertyIntoHostFunction(
): string {
const [propertyTypeAnnotation] =
unwrapNullable<NativeModuleFunctionTypeAnnotation>(property.typeAnnotation);
const isVoid =
propertyTypeAnnotation.returnTypeAnnotation.type === 'VoidTypeAnnotation';
return HostFunctionTemplate({
hasteModuleName,
methodName: property.name,
isVoid,
returnTypeAnnotation: propertyTypeAnnotation.returnTypeAnnotation,
args: propertyTypeAnnotation.params.map((p, i) =>
serializeArg(p, i, resolveAlias),
),

Просмотреть файл

@ -62,13 +62,16 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getArrays(jsi
return jsi::Value::undefined();
}
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getNullableObject(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getNullableObject(rt);
auto result = static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getNullableObject(rt);
return result ? jsi::Value(std::move(*result)) : jsi::Value::null();
}
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getNullableGenericObject(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getNullableGenericObject(rt);
auto result = static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getNullableGenericObject(rt);
return result ? jsi::Value(std::move(*result)) : jsi::Value::null();
}
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getNullableArray(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getNullableArray(rt);
auto result = static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getNullableArray(rt);
return result ? jsi::Value(std::move(*result)) : jsi::Value::null();
}
NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
@ -109,7 +112,8 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getMixed(jsi:
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getMixed(rt, jsi::Value(rt, args[0]));
}
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getNullableNumberFromNullableAlias(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getNullableNumberFromNullableAlias(rt, args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt)));
auto result = static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getNullableNumberFromNullableAlias(rt, args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt)));
return result ? jsi::Value(std::move(*result)) : jsi::Value::null();
}
NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)