Summary: X-link: https://github.com/facebook/react-native/pull/37115 Pull Request resolved: https://github.com/facebook/yoga/pull/1267 This is an existing bitset enum in the API. Use the facility added in the last diff to add flag operators to it, to avoid the need for casting, and to make it clearer in the generated YGEnums.h that it is a bitset. Reviewed By: rshest Differential Revision: D45341504 fbshipit-source-id: 0b80588f3e2e167d4c1c722c6d6608408dd617ba
307 lines
9.9 KiB
Python
307 lines
9.9 KiB
Python
# 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.
|
|
|
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
|
|
|
import os
|
|
|
|
|
|
ENUMS = {
|
|
"Direction": ["Inherit", "LTR", "RTL"],
|
|
"Unit": ["Undefined", "Point", "Percent", "Auto"],
|
|
"FlexDirection": ["Column", "ColumnReverse", "Row", "RowReverse"],
|
|
"Justify": [
|
|
"FlexStart",
|
|
"Center",
|
|
"FlexEnd",
|
|
"SpaceBetween",
|
|
"SpaceAround",
|
|
"SpaceEvenly",
|
|
],
|
|
"Overflow": ["Visible", "Hidden", "Scroll"],
|
|
"Align": [
|
|
"Auto",
|
|
"FlexStart",
|
|
"Center",
|
|
"FlexEnd",
|
|
"Stretch",
|
|
"Baseline",
|
|
"SpaceBetween",
|
|
"SpaceAround",
|
|
],
|
|
"PositionType": ["Static", "Relative", "Absolute"],
|
|
"Display": ["Flex", "None"],
|
|
"Wrap": ["NoWrap", "Wrap", "WrapReverse"],
|
|
"MeasureMode": ["Undefined", "Exactly", "AtMost"],
|
|
"Dimension": ["Width", "Height"],
|
|
"Edge": [
|
|
"Left",
|
|
"Top",
|
|
"Right",
|
|
"Bottom",
|
|
"Start",
|
|
"End",
|
|
"Horizontal",
|
|
"Vertical",
|
|
"All",
|
|
],
|
|
"NodeType": ["Default", "Text"],
|
|
"LogLevel": ["Error", "Warn", "Info", "Debug", "Verbose", "Fatal"],
|
|
"ExperimentalFeature": [
|
|
# Mimic web flex-basis behavior (experiment may be broken)
|
|
"WebFlexBasis",
|
|
# Conformance fix: https://github.com/facebook/yoga/pull/1028
|
|
"AbsolutePercentageAgainstPaddingEdge",
|
|
# Conformance fix: https://github.com/facebook/yoga/pull/1028
|
|
"FixAbsoluteTrailingColumnMargin",
|
|
],
|
|
"PrintOptions": [
|
|
("Layout", 1 << 0),
|
|
("Style", 1 << 1),
|
|
("Children", 1 << 2),
|
|
],
|
|
"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
|
|
# manually from all but YogaLogLevel. TODO: Is it safe to remove from it as
|
|
# well?
|
|
DO_NOT_STRIP = ["LogLevel"]
|
|
|
|
BITSET_ENUMS = ["PrintOptions", "Errata"]
|
|
|
|
|
|
def get_license(ext):
|
|
prologue = "/**" if ext == "js" else "/*"
|
|
return """{}
|
|
* 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.
|
|
*/
|
|
|
|
// @{} by enums.py
|
|
|
|
""".format(
|
|
prologue, "generated"
|
|
)
|
|
|
|
|
|
def to_java_upper(symbol):
|
|
symbol = str(symbol)
|
|
out = ""
|
|
for i in range(0, len(symbol)):
|
|
c = symbol[i]
|
|
if str.istitle(c) and i is not 0 and not str.istitle(symbol[i - 1]):
|
|
out += "_"
|
|
out += c.upper()
|
|
return out
|
|
|
|
|
|
def to_log_lower(symbol):
|
|
symbol = str(symbol)
|
|
out = ""
|
|
for i in range(0, len(symbol)):
|
|
c = symbol[i]
|
|
if str.istitle(c) and i is not 0 and not str.istitle(symbol[i - 1]):
|
|
out += "-"
|
|
out += c.lower()
|
|
return out
|
|
|
|
|
|
root = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
# write out C & Objective-C headers
|
|
with open(root + "/yoga/YGEnums.h", "w") as f:
|
|
f.write(get_license("cpp"))
|
|
f.write("#pragma once\n")
|
|
f.write('#include "YGMacros.h"\n\n')
|
|
f.write("// clang-format off\n\n\n")
|
|
|
|
f.write("YG_EXTERN_C_BEGIN\n\n")
|
|
items = sorted(ENUMS.items())
|
|
for name, values in items:
|
|
if isinstance(values[0], tuple):
|
|
f.write("YG_ENUM_DECL(\n")
|
|
else:
|
|
f.write("YG_ENUM_SEQ_DECL(\n")
|
|
|
|
f.write(" YG%s,\n" % name)
|
|
for value in values:
|
|
if isinstance(value, tuple):
|
|
f.write(" YG%s%s = %d" % (name, value[0], value[1]))
|
|
else:
|
|
f.write(" YG%s%s" % (name, value))
|
|
if value == values[-1]:
|
|
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")
|
|
|
|
# write out C body for printing
|
|
with open(root + "/yoga/YGEnums.cpp", "w") as f:
|
|
f.write(get_license("cpp"))
|
|
f.write('#include "YGEnums.h"\n\n')
|
|
items = sorted(ENUMS.items())
|
|
for name, values in items:
|
|
f.write("const char* YG%sToString(const YG%s value) {\n" % (name, name))
|
|
f.write(" switch (value) {\n")
|
|
for value in values:
|
|
if isinstance(value, tuple):
|
|
f.write(" case YG%s%s:\n" % (name, value[0]))
|
|
f.write(' return "%s";\n' % to_log_lower(value[0]))
|
|
else:
|
|
f.write(" case YG%s%s:\n" % (name, value))
|
|
f.write(' return "%s";\n' % to_log_lower(value))
|
|
f.write(" }\n")
|
|
f.write(' return "unknown";\n')
|
|
f.write("}\n")
|
|
if name != items[-1][0]:
|
|
f.write("\n")
|
|
|
|
# write out java files
|
|
for name, values in sorted(ENUMS.items()):
|
|
with open(root + "/java/com/facebook/yoga/Yoga%s.java" % name, "w") as f:
|
|
f.write(get_license("java"))
|
|
f.write("package com.facebook.yoga;\n\n")
|
|
if name in DO_NOT_STRIP:
|
|
f.write("import com.facebook.yoga.annotations.DoNotStrip;\n\n")
|
|
f.write("@DoNotStrip\n")
|
|
f.write("public enum Yoga%s {\n" % name)
|
|
if len(values) > 0:
|
|
for value in values:
|
|
if isinstance(value, tuple):
|
|
f.write(" %s(%d)" % (to_java_upper(value[0]), value[1]))
|
|
else:
|
|
f.write(" %s(%d)" % (to_java_upper(value), values.index(value)))
|
|
if values.index(value) is len(values) - 1:
|
|
f.write(";\n")
|
|
else:
|
|
f.write(",\n")
|
|
else:
|
|
f.write("__EMPTY(-1);")
|
|
f.write("\n")
|
|
f.write(" private final int mIntValue;\n")
|
|
f.write("\n")
|
|
f.write(" Yoga%s(int intValue) {\n" % name)
|
|
f.write(" mIntValue = intValue;\n")
|
|
f.write(" }\n")
|
|
f.write("\n")
|
|
f.write(" public int intValue() {\n")
|
|
f.write(" return mIntValue;\n")
|
|
f.write(" }\n")
|
|
f.write("\n")
|
|
if name in DO_NOT_STRIP:
|
|
f.write(" @DoNotStrip\n")
|
|
f.write(" public static Yoga%s fromInt(int value) {\n" % name)
|
|
f.write(" switch (value) {\n")
|
|
for value in values:
|
|
if isinstance(value, tuple):
|
|
f.write(
|
|
" case %d: return %s;\n" % (value[1], to_java_upper(value[0]))
|
|
)
|
|
else:
|
|
f.write(
|
|
" case %d: return %s;\n"
|
|
% (values.index(value), to_java_upper(value))
|
|
)
|
|
f.write(
|
|
' default: throw new IllegalArgumentException("Unknown enum value: " + value);\n'
|
|
)
|
|
f.write(" }\n")
|
|
f.write(" }\n")
|
|
f.write("}\n")
|
|
|
|
# write out csharp files
|
|
for name, values in sorted(ENUMS.items()):
|
|
with open(root + "/csharp/Facebook.Yoga/Yoga%s.cs" % name, "w") as f:
|
|
f.write(get_license("cs"))
|
|
f.write("namespace Facebook.Yoga\n{\n")
|
|
if isinstance(next(iter(values or []), None), tuple):
|
|
f.write(" [System.Flags]\n")
|
|
f.write(" public enum Yoga%s\n {\n" % name)
|
|
for value in values:
|
|
if isinstance(value, tuple):
|
|
f.write(" %s = %d,\n" % (value[0], value[1]))
|
|
else:
|
|
f.write(" %s,\n" % value)
|
|
f.write(" }\n")
|
|
f.write("}\n")
|
|
|
|
# write out javascript file
|
|
with open(root + "/javascript/src_js/generated/YGEnums.js", "w") as f:
|
|
f.write(get_license("js"))
|
|
items = sorted(ENUMS.items())
|
|
for name, values in items:
|
|
base = 0
|
|
for value in values:
|
|
value_arg = value[0] if isinstance(value, tuple) else value
|
|
ordinal_arg = value[1] if isinstance(value, tuple) else base
|
|
|
|
f.write(
|
|
"exports.%s_%s = %d;\n"
|
|
% (to_java_upper(name), to_java_upper(value_arg), ordinal_arg)
|
|
)
|
|
base = ordinal_arg + 1
|
|
|
|
if name != items[-1][0]:
|
|
f.write("\n")
|
|
|
|
with open(root + "/javascript/src_js/generated/YGEnums.d.ts", "w") as f:
|
|
f.write(get_license("js"))
|
|
|
|
for name, values in sorted(ENUMS.items()):
|
|
base = 0
|
|
for value in values:
|
|
value_arg = value[0] if isinstance(value, tuple) else value
|
|
ordinal_arg = value[1] if isinstance(value, tuple) else base
|
|
|
|
f.write(
|
|
(
|
|
"type {name}_{value} = {ordinal} & ['{name}']\n"
|
|
+ "export const {name}_{value}: {name}_{value};\n\n"
|
|
).format(
|
|
name=to_java_upper(name),
|
|
value=to_java_upper(value_arg),
|
|
ordinal=ordinal_arg,
|
|
)
|
|
)
|
|
|
|
base = ordinal_arg + 1
|
|
|
|
f.write("\n")
|
|
|
|
for name, values in sorted(ENUMS.items()):
|
|
f.write("export type {} =\n".format(name))
|
|
for value in values:
|
|
unpackedValue = value[0] if isinstance(value, tuple) else value
|
|
f.write(
|
|
" | typeof {}_{}".format(
|
|
to_java_upper(name), to_java_upper(unpackedValue)
|
|
)
|
|
)
|
|
if values[-1] == value:
|
|
f.write(";\n")
|
|
else:
|
|
f.write("\n")
|
|
|
|
f.write("\n")
|