Add codegen support for DimensionValue for components (#35953)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35953

DimensionValue is a reserved prop type that can be a number or string (such as '50%'). On Java, it will get converted to a YogaValue (converter added to this diff); on C++ it will get converted to a YGValue (converter already exists as it's used in Fabric).

Changelog:
[Internal][Added] - Add codegen support for DimensionValue for components

Reviewed By: cipolleschi

Differential Revision: D42650799

fbshipit-source-id: 1d2bc30bbd93837dedbbb4c74f814963c8140957
This commit is contained in:
Genki Kondo
2023-01-26 18:52:10 -08:00
committed by Facebook GitHub Bot
parent 97e707d897
commit d3cc48d9a6
54 changed files with 1472 additions and 80 deletions
@@ -1,4 +1,4 @@
load("//tools/build_defs/oss:rn_defs.bzl", "IS_OSS_BUILD", "react_native_dep", "react_native_target", "react_native_tests_target", "rn_android_library")
load("//tools/build_defs/oss:rn_defs.bzl", "IS_OSS_BUILD", "YOGA_TARGET", "react_native_dep", "react_native_target", "react_native_tests_target", "rn_android_library")
INTERFACES = [
"Dynamic.java",
@@ -34,6 +34,7 @@ rn_android_library(
"PUBLIC",
],
deps = [
YOGA_TARGET,
react_native_dep("java/com/facebook/debug/debugoverlay/model:model"),
react_native_dep("java/com/facebook/systrace:systrace"),
react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"),
@@ -0,0 +1,33 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.bridge;
import androidx.annotation.Nullable;
import com.facebook.yoga.YogaUnit;
import com.facebook.yoga.YogaValue;
public class DimensionPropConverter {
@Nullable
public static YogaValue getDimension(@Nullable Object value) {
if (value == null) {
return null;
}
if (value instanceof Double) {
return new YogaValue(((Double) value).floatValue(), YogaUnit.POINT);
}
if (value instanceof String) {
return YogaValue.parse((String) value);
}
throw new JSApplicationCausedNativeException(
"DimensionValue: the value must be a number or string.");
}
}
@@ -1,4 +1,4 @@
load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_target", "rn_java_annotation_processor", "rn_java_library")
load("//tools/build_defs/oss:rn_defs.bzl", "YOGA_TARGET", "react_native_dep", "react_native_target", "rn_java_annotation_processor", "rn_java_library")
rn_java_annotation_processor(
name = "processing",
@@ -21,6 +21,7 @@ rn_java_library(
source = "7",
target = "7",
deps = [
YOGA_TARGET,
react_native_dep("third-party/java/infer-annotations:infer-annotations"),
react_native_dep("third-party/java/javapoet:javapoet"),
react_native_dep("third-party/java/jsr-305:jsr-305"),
@@ -21,6 +21,7 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.react.uimanager.annotations.ReactPropertyHolder;
import com.facebook.yoga.YogaValue;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.JavaFile;
@@ -69,14 +70,13 @@ public class ReactPropertyProcessor extends AbstractProcessor {
private static final Map<TypeName, String> DEFAULT_TYPES;
private static final Set<TypeName> BOXED_PRIMITIVES;
private static final TypeName PROPS_TYPE =
ClassName.get("com.facebook.react.uimanager", "ReactStylesDiffMap");
private static final TypeName OBJECT_TYPE = TypeName.get(Object.class);
private static final TypeName STRING_TYPE = TypeName.get(String.class);
private static final TypeName READABLE_MAP_TYPE = TypeName.get(ReadableMap.class);
private static final TypeName READABLE_ARRAY_TYPE = TypeName.get(ReadableArray.class);
private static final TypeName DYNAMIC_TYPE = TypeName.get(Dynamic.class);
private static final TypeName DYNAMIC_FROM_OBJECT_TYPE = TypeName.get(DynamicFromObject.class);
private static final TypeName YOGA_VALUE_TYPE = TypeName.get(YogaValue.class);
private static final TypeName VIEW_MANAGER_TYPE =
ClassName.get("com.facebook.react.uimanager", "ViewManager");
@@ -120,6 +120,7 @@ public class ReactPropertyProcessor extends AbstractProcessor {
DEFAULT_TYPES.put(READABLE_ARRAY_TYPE, "Array");
DEFAULT_TYPES.put(READABLE_MAP_TYPE, "Map");
DEFAULT_TYPES.put(DYNAMIC_TYPE, "Dynamic");
DEFAULT_TYPES.put(YOGA_VALUE_TYPE, "YogaValue");
BOXED_PRIMITIVES = new HashSet<>();
BOXED_PRIMITIVES.add(TypeName.BOOLEAN.box());
@@ -369,6 +370,9 @@ public class ReactPropertyProcessor extends AbstractProcessor {
return builder.add("($L)value", READABLE_MAP_TYPE);
} else if (propertyType.equals(DYNAMIC_TYPE)) {
return builder.add("new $L(value)", DYNAMIC_FROM_OBJECT_TYPE);
} else if (propertyType.equals(YOGA_VALUE_TYPE)) {
return builder.add(
"$T.getDimension(value)", com.facebook.react.bridge.DimensionPropConverter.class);
}
if (BOXED_PRIMITIVES.contains(propertyType)) {
@@ -420,7 +424,7 @@ public class ReactPropertyProcessor extends AbstractProcessor {
CodeBlock.Builder builder = CodeBlock.builder();
for (PropertyInfo propertyInfo : properties) {
try {
String typeName = getPropertypTypeName(propertyInfo.mProperty, propertyInfo.propertyType);
String typeName = getPropertyTypeName(propertyInfo.mProperty, propertyInfo.propertyType);
builder.addStatement("props.put($S, $S)", propertyInfo.mProperty.name(), typeName);
} catch (IllegalArgumentException e) {
throw new ReactPropertyException(e.getMessage(), propertyInfo);
@@ -430,7 +434,7 @@ public class ReactPropertyProcessor extends AbstractProcessor {
return builder.build();
}
private static String getPropertypTypeName(Property property, TypeName propertyType) {
private static String getPropertyTypeName(Property property, TypeName propertyType) {
String defaultType = DEFAULT_TYPES.get(propertyType);
String useDefaultType =
property instanceof RegularProperty