Namespaced and TypeScript Enums (#1285)
Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1285 Enums are currently exposed to the JS package as constants (e.g. `import {ERRATA_NONE} from 'yoga-layout'`). This exports enums in the form of `import {Errata} from 'yoga-layout'` then `Errata.None`. It would be more ergonomic for these to be string union based enums instead, but right now it is a pretty thin wrapper around the native API, we need ordinal values to do things with bit masks, and folks have wanted to serialize them before. Reviewed By: yungsters Differential Revision: D45570417 fbshipit-source-id: dbfd330e939051d0c16460a4d2a996f88f98875c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
aa812d0e48
commit
104646d8ca
126
enums.py
Normal file → Executable file
126
enums.py
Normal file → Executable file
@@ -1,13 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
# 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"],
|
||||
@@ -78,50 +76,44 @@ ENUMS = {
|
||||
],
|
||||
}
|
||||
|
||||
# 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 """{}
|
||||
return f"""{"/**" if ext == "js" else "/*"}
|
||||
* 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
|
||||
// @{"generated"} by enums.py
|
||||
|
||||
""".format(
|
||||
prologue, "generated"
|
||||
)
|
||||
"""
|
||||
|
||||
|
||||
def _format_name(symbol, delimiter=None, transform=None):
|
||||
symbol = str(symbol)
|
||||
out = ""
|
||||
for i in range(0, len(symbol)):
|
||||
c = symbol[i]
|
||||
if str.istitle(c) and i != 0 and not str.istitle(symbol[i - 1]):
|
||||
out += delimiter or ""
|
||||
if transform is None:
|
||||
out += c
|
||||
else:
|
||||
out += getattr(c, transform)()
|
||||
return out
|
||||
|
||||
|
||||
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
|
||||
return _format_name(symbol, "_", "upper")
|
||||
|
||||
|
||||
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
|
||||
def to_hyphenated_lower(symbol):
|
||||
return _format_name(symbol, "-", "lower")
|
||||
|
||||
|
||||
root = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -167,10 +159,10 @@ with open(root + "/yoga/YGEnums.cpp", "w") as f:
|
||||
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]))
|
||||
f.write(' return "%s";\n' % to_hyphenated_lower(value[0]))
|
||||
else:
|
||||
f.write(" case YG%s%s:\n" % (name, value))
|
||||
f.write(' return "%s";\n' % to_log_lower(value))
|
||||
f.write(' return "%s";\n' % to_hyphenated_lower(value))
|
||||
f.write(" }\n")
|
||||
f.write(' return "unknown";\n')
|
||||
f.write("}\n")
|
||||
@@ -246,61 +238,27 @@ for name, values in sorted(ENUMS.items()):
|
||||
f.write(" }\n")
|
||||
f.write("}\n")
|
||||
|
||||
# write out javascript file
|
||||
with open(root + "/javascript/src/generated/YGEnums.js", "w") as f:
|
||||
# write out TypeScript file
|
||||
with open(root + "/javascript/src/generated/YGEnums.ts", "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
|
||||
enums = sorted(ENUMS.items())
|
||||
for enum_name, ordinals in enums:
|
||||
f.write(f"export enum {enum_name} {{\n")
|
||||
for ordinal_index, ordinal in enumerate(ordinals):
|
||||
ordinal_name = ordinal[0] if isinstance(ordinal, tuple) else ordinal
|
||||
ordinal_value = ordinal[1] if isinstance(ordinal, tuple) else ordinal_index
|
||||
f.write(f" {ordinal_name} = {ordinal_value},\n")
|
||||
|
||||
f.write("}\n\n")
|
||||
|
||||
f.write("const constants = {\n")
|
||||
for enum_name, ordinals in enums:
|
||||
for ordinal in ordinals:
|
||||
ordinal_name = ordinal[0] if isinstance(ordinal, tuple) else ordinal
|
||||
ordinal_value = ordinal[1] if isinstance(ordinal, tuple) else ordinal_index
|
||||
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/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 declare const {name}_{value}: {name}_{value};\n\n"
|
||||
).format(
|
||||
name=to_java_upper(name),
|
||||
value=to_java_upper(value_arg),
|
||||
ordinal=ordinal_arg,
|
||||
)
|
||||
f" {to_java_upper(enum_name)}_{to_java_upper(ordinal_name)}: {enum_name}.{ordinal_name},\n"
|
||||
)
|
||||
|
||||
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")
|
||||
f.write("}\n")
|
||||
f.write("export default constants")
|
||||
|
Reference in New Issue
Block a user