From 1d82290f993f411c8d30e8b92a345e117ad49c52 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 25 Apr 2023 17:46:39 -0700 Subject: [PATCH] Add YGErrata Enum (#1256) Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1256 X-link: https://github.com/facebook/react-native/pull/37076 This adds a `YGErrata` bitset enum matching the API and guarantees described in https://github.com/facebook/yoga/issues/1247. It is hooked up in later diffs. There are a couple of `YGExperimentalFeature` values that belong here, but keeping the current options means that the default `YGErrataNone` corresponds to existing default behavior, letting us stage the series of changes as: 1. Implement errata API 2. Update internal Yoga users we want to de-risk to `YGErrataClassic` or `YGErrataAll` (if setting `UseLegacyStretchBehaviour`) 3. Add new errata, changing Yoga defaults to be conformant, while letting internal apps opt into compatibility modes pending experimentation. I also added a macro to let C++ users of Yoga perform bitwise operations on the enum without casting (already available for C users). Reviewed By: rshest Differential Revision: D45254098 fbshipit-source-id: 4471715fbd1e3110972091077fdc5208002b0da9 --- csharp/Facebook.Yoga/YogaErrata.cs | 20 +++++++++++ enums.py | 17 +++++++++ java/com/facebook/yoga/YogaErrata.java | 37 +++++++++++++++++++ javascript/src_js/generated/YGEnums.d.ts | 19 ++++++++++ javascript/src_js/generated/YGEnums.js | 5 +++ yoga/YGEnums.cpp | 14 ++++++++ yoga/YGEnums.h | 8 +++++ yoga/YGMacros.h | 46 ++++++++++++++++++++++++ 8 files changed, 166 insertions(+) create mode 100644 csharp/Facebook.Yoga/YogaErrata.cs create mode 100644 java/com/facebook/yoga/YogaErrata.java diff --git a/csharp/Facebook.Yoga/YogaErrata.cs b/csharp/Facebook.Yoga/YogaErrata.cs new file mode 100644 index 0000000000..d123f50fbd --- /dev/null +++ b/csharp/Facebook.Yoga/YogaErrata.cs @@ -0,0 +1,20 @@ +/* + * 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. + */ + +// @generated by enums.py + +namespace Facebook.Yoga +{ + [System.Flags] + public enum YogaErrata + { + None = 0, + StretchFlexBasis = 1, + All = 2147483647, + Classic = 2147483646, + } +} diff --git a/enums.py b/enums.py index d836ff5ed1..146909ad0c 100644 --- a/enums.py +++ b/enums.py @@ -59,6 +59,19 @@ ], "PrintOptions": [("Layout", 1), ("Style", 2), ("Children", 4)], "Gutter": ["Column", "Row", "All"], + # Known incorrect behavior which can be enabled for compatibility + "Errata": [ + # Default: Standards conformant mode + ("None", 0), + # Allows main-axis flex basis to be stretched without flexGrow being + # set (previously referred to as "UseLegacyStretchBehaviour") + ("StretchFlexBasis", 1 << 0), + # Enable all incorrect behavior (preserve compatibility) + ("All", 0x7FFFFFFF), + # Enable all errata except for "StretchFlexBasis" (Defaults behavior + # before Yoga 2.0) + ("Classic", 0x7FFFFFFF & (~(1 << 0))), + ], } # Generated Java enums used to emit @DoNotStrip, but D17519844 removed them @@ -66,6 +79,8 @@ # well? DO_NOT_STRIP = ["LogLevel"] +BITSET_ENUMS = ["Errata"] + def get_license(ext): prologue = "/**" if ext == "js" else "/*" @@ -132,6 +147,8 @@ def to_log_lower(symbol): f.write(")\n") else: f.write(",\n") + if name in BITSET_ENUMS: + f.write("YG_DEFINE_ENUM_FLAG_OPERATORS(YG%s)\n" % name) f.write("\n") f.write("YG_EXTERN_C_END\n") diff --git a/java/com/facebook/yoga/YogaErrata.java b/java/com/facebook/yoga/YogaErrata.java new file mode 100644 index 0000000000..6ae5ac0e7c --- /dev/null +++ b/java/com/facebook/yoga/YogaErrata.java @@ -0,0 +1,37 @@ +/* + * 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. + */ + +// @generated by enums.py + +package com.facebook.yoga; + +public enum YogaErrata { + NONE(0), + STRETCH_FLEX_BASIS(1), + ALL(2147483647), + CLASSIC(2147483646); + + private final int mIntValue; + + YogaErrata(int intValue) { + mIntValue = intValue; + } + + public int intValue() { + return mIntValue; + } + + public static YogaErrata fromInt(int value) { + switch (value) { + case 0: return NONE; + case 1: return STRETCH_FLEX_BASIS; + case 2147483647: return ALL; + case 2147483646: return CLASSIC; + default: throw new IllegalArgumentException("Unknown enum value: " + value); + } + } +} diff --git a/javascript/src_js/generated/YGEnums.d.ts b/javascript/src_js/generated/YGEnums.d.ts index 323a6b05ff..cd31ee7de3 100644 --- a/javascript/src_js/generated/YGEnums.d.ts +++ b/javascript/src_js/generated/YGEnums.d.ts @@ -84,6 +84,19 @@ type EDGE_ALL = 8 & ['EDGE'] export const EDGE_ALL: EDGE_ALL; +type ERRATA_NONE = 0 & ['ERRATA'] +export const ERRATA_NONE: ERRATA_NONE; + +type ERRATA_STRETCH_FLEX_BASIS = 1 & ['ERRATA'] +export const ERRATA_STRETCH_FLEX_BASIS: ERRATA_STRETCH_FLEX_BASIS; + +type ERRATA_ALL = 2147483647 & ['ERRATA'] +export const ERRATA_ALL: ERRATA_ALL; + +type ERRATA_CLASSIC = 2147483646 & ['ERRATA'] +export const ERRATA_CLASSIC: ERRATA_CLASSIC; + + type EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS = 0 & ['EXPERIMENTAL_FEATURE'] export const EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS: EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS; @@ -259,6 +272,12 @@ export type Edge = | typeof EDGE_VERTICAL | typeof EDGE_ALL; +export type Errata = + | typeof ERRATA_NONE + | typeof ERRATA_STRETCH_FLEX_BASIS + | typeof ERRATA_ALL + | typeof ERRATA_CLASSIC; + export type ExperimentalFeature = | typeof EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS | typeof EXPERIMENTAL_FEATURE_ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE diff --git a/javascript/src_js/generated/YGEnums.js b/javascript/src_js/generated/YGEnums.js index 0caa931d11..69c86f4aa4 100644 --- a/javascript/src_js/generated/YGEnums.js +++ b/javascript/src_js/generated/YGEnums.js @@ -36,6 +36,11 @@ exports.EDGE_HORIZONTAL = 6; exports.EDGE_VERTICAL = 7; exports.EDGE_ALL = 8; +exports.ERRATA_NONE = 0; +exports.ERRATA_STRETCH_FLEX_BASIS = 1; +exports.ERRATA_ALL = 2147483647; +exports.ERRATA_CLASSIC = 2147483646; + exports.EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS = 0; exports.EXPERIMENTAL_FEATURE_ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE = 1; exports.EXPERIMENTAL_FEATURE_FIX_ABSOLUTE_TRAILING_COLUMN_MARGIN = 2; diff --git a/yoga/YGEnums.cpp b/yoga/YGEnums.cpp index acb1bd072a..50cc418a91 100644 --- a/yoga/YGEnums.cpp +++ b/yoga/YGEnums.cpp @@ -87,6 +87,20 @@ const char* YGEdgeToString(const YGEdge value) { return "unknown"; } +const char* YGErrataToString(const YGErrata value) { + switch (value) { + case YGErrataNone: + return "none"; + case YGErrataStretchFlexBasis: + return "stretch-flex-basis"; + case YGErrataAll: + return "all"; + case YGErrataClassic: + return "classic"; + } + return "unknown"; +} + const char* YGExperimentalFeatureToString(const YGExperimentalFeature value) { switch (value) { case YGExperimentalFeatureWebFlexBasis: diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index 834e5f669c..13840694b9 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -54,6 +54,14 @@ YG_ENUM_SEQ_DECL( YGEdgeVertical, YGEdgeAll) +YG_ENUM_DECL( + YGErrata, + YGErrataNone = 0, + YGErrataStretchFlexBasis = 1, + YGErrataAll = 2147483647, + YGErrataClassic = 2147483646) +YG_DEFINE_ENUM_FLAG_OPERATORS(YGErrata) + YG_ENUM_SEQ_DECL( YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis, diff --git a/yoga/YGMacros.h b/yoga/YGMacros.h index 13b3c9b4f5..0ce8c2eed4 100644 --- a/yoga/YGMacros.h +++ b/yoga/YGMacros.h @@ -7,6 +7,10 @@ #pragma once +#ifdef __cplusplus +#include +#endif + #ifdef __cplusplus #define YG_EXTERN_C_BEGIN extern "C" { #define YG_EXTERN_C_END } @@ -40,6 +44,48 @@ #define YG_ENUM_END(name) name #endif +#ifdef __cplusplus +#define YG_DEFINE_ENUM_FLAG_OPERATORS(name) \ + extern "C++" { \ + constexpr inline name operator~(name a) { \ + return static_cast( \ + ~static_cast::type>(a)); \ + } \ + constexpr inline name operator|(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) | \ + static_cast::type>(b)); \ + } \ + constexpr inline name operator&(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) & \ + static_cast::type>(b)); \ + } \ + constexpr inline name operator^(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) ^ \ + static_cast::type>(b)); \ + } \ + inline name& operator|=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) |= \ + static_cast::type>(b)); \ + } \ + inline name& operator&=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) &= \ + static_cast::type>(b)); \ + } \ + inline name& operator^=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) ^= \ + static_cast::type>(b)); \ + } \ + } +#else +#define YG_DEFINE_ENUM_FLAG_OPERATORS(name) +#endif + #ifdef __cplusplus namespace facebook { namespace yoga {