From b88cf7ff67317559ae378a19138a0ea7ffdf5df6 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 15 Nov 2019 05:10:33 -0800 Subject: [PATCH 01/87] use owner's width for resolving the margin and padding for node Summary: The margin and padding are resolved incorrectly for leaf nodes (nodes with measure function set) if margin and padding are used in percentages. Here we were using node's width instead of container width to calculate the margin and padding. Fixed this to use container's width. ## Changelog: [General][Yoga] : Fixed an issue where margin and padding were resolved incorrectly for leaf nodes (nodes with measure function set) if margin and padding are used in percentages. Reviewed By: alickbass Differential Revision: D17130520 fbshipit-source-id: ac904d432f121973e7739debd9136909b5ca1427 --- tests/YGMeasureTest.cpp | 4 ++-- yoga/Yoga.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/YGMeasureTest.cpp b/tests/YGMeasureTest.cpp index 38c28059..baeb0ae8 100644 --- a/tests/YGMeasureTest.cpp +++ b/tests/YGMeasureTest.cpp @@ -686,9 +686,9 @@ TEST(YogaTest, percent_with_text_node) { ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); - ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); YGNodeFreeRecursive(root); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 04d199a3..41de5119 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1670,13 +1670,13 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( "Expected node to have custom measure function"); const float paddingAndBorderAxisRow = - YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth); - const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis( - node, YGFlexDirectionColumn, availableWidth); + YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); + const float paddingAndBorderAxisColumn = + YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth); const float marginAxisRow = - node->getMarginForAxis(YGFlexDirectionRow, availableWidth).unwrap(); + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); const float marginAxisColumn = - node->getMarginForAxis(YGFlexDirectionColumn, availableWidth).unwrap(); + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); // We want to make sure we don't call measure with negative size const float innerWidth = YGFloatIsUndefined(availableWidth) From 7ec0ef847029d895ee32ac5cf663f1e5cac6dd02 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 15 Nov 2019 05:10:33 -0800 Subject: [PATCH 02/87] add test for margin and padding percent applied on leaf nodes with measure function Summary: Add tests for using margin and padding percent on nodes with measure function set on them Reviewed By: alickbass Differential Revision: D17130693 fbshipit-source-id: 9a5c963671f7649dead459969b008335f15e45ce --- tests/YGMeasureTest.cpp | 215 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) diff --git a/tests/YGMeasureTest.cpp b/tests/YGMeasureTest.cpp index baeb0ae8..b5bbe5d4 100644 --- a/tests/YGMeasureTest.cpp +++ b/tests/YGMeasureTest.cpp @@ -654,6 +654,19 @@ static YGSize _measure_90_10( }; } +static YGSize _measure_100_100( + YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + + return YGSize{ + .width = 100, + .height = 100, + }; +} + TEST(YogaTest, percent_with_text_node) { const YGConfigRef config = YGConfigNew(); @@ -694,3 +707,205 @@ TEST(YogaTest, percent_with_text_node) { YGConfigFree(config); } + +TEST(YogaTest, percent_margin_with_measure_func) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 0); + root_child0->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeStyleSetMargin(root_child1, YGEdgeTop, 100); + root_child1->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeStyleSetMarginPercent(root_child2, YGEdgeTop, 10); + root_child2->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 100); + YGNodeStyleSetHeight(root_child3, 100); + YGNodeStyleSetMarginPercent(root_child3, YGEdgeTop, 20); + root_child3->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_padding_with_measure_func) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetAlignContent(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 0); + root_child0->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeStyleSetPadding(root_child1, YGEdgeTop, 100); + root_child1->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetPaddingPercent(root_child2, YGEdgeTop, 10); + root_child2->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetPaddingPercent(root_child3, YGEdgeTop, 20); + root_child3->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_padding_and_percent_margin_with_measure_func) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetAlignContent(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 0); + root_child0->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeStyleSetPadding(root_child1, YGEdgeTop, 100); + root_child1->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetPaddingPercent(root_child2, YGEdgeTop, 10); + YGNodeStyleSetMarginPercent(root_child2, YGEdgeTop, 10); + root_child2->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetPaddingPercent(root_child3, YGEdgeTop, 20); + YGNodeStyleSetMarginPercent(root_child3, YGEdgeTop, 20); + root_child3->setMeasureFunc(_measure_100_100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} From cd0191c2470523b996a379a6761d3a57b1b83f45 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 15 Nov 2019 06:37:39 -0800 Subject: [PATCH 03/87] not using templates for updating styles which are used via bitfield Summary: We want completely remove usages of Bitfield as it uses templates which bloats binary size This stack will reduce 2.2 Kb in binary size bringing it down to 61.3KB on armv7 In this diff we are removing usage of template while updating styles. ## Changelog: [Internal][Yoga] : Not using templates for updating styles Reviewed By: astreet Differential Revision: D18519570 fbshipit-source-id: 2324088b8c63154f818b1da1edf24c0533e10082 --- yoga/Yoga.cpp | 54 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 41de5119..1821c867 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -582,7 +582,10 @@ void updateIndexedStyleProp( YOGA_EXPORT void YGNodeStyleSetDirection( const YGNodeRef node, const YGDirection value) { - updateStyle(node, &YGStyle::direction, value); + if (node->getStyle().direction() != value) { + node->getStyle().direction() = value; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { return node->getStyle().direction(); @@ -591,8 +594,10 @@ YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetFlexDirection( const YGNodeRef node, const YGFlexDirection flexDirection) { - updateStyle( - node, &YGStyle::flexDirection, flexDirection); + if (node->getStyle().flexDirection() != flexDirection) { + node->getStyle().flexDirection() = flexDirection; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { @@ -602,8 +607,10 @@ YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetJustifyContent( const YGNodeRef node, const YGJustify justifyContent) { - updateStyle( - node, &YGStyle::justifyContent, justifyContent); + if (node->getStyle().justifyContent() != justifyContent) { + node->getStyle().justifyContent() = justifyContent; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { return node->getStyle().justifyContent(); @@ -612,8 +619,10 @@ YOGA_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetAlignContent( const YGNodeRef node, const YGAlign alignContent) { - updateStyle( - node, &YGStyle::alignContent, alignContent); + if (node->getStyle().alignContent() != alignContent) { + node->getStyle().alignContent() = alignContent; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { return node->getStyle().alignContent(); @@ -622,7 +631,10 @@ YOGA_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetAlignItems( const YGNodeRef node, const YGAlign alignItems) { - updateStyle(node, &YGStyle::alignItems, alignItems); + if (node->getStyle().alignItems() != alignItems) { + node->getStyle().alignItems() = alignItems; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { return node->getStyle().alignItems(); @@ -631,7 +643,10 @@ YOGA_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetAlignSelf( const YGNodeRef node, const YGAlign alignSelf) { - updateStyle(node, &YGStyle::alignSelf, alignSelf); + if (node->getStyle().alignSelf() != alignSelf) { + node->getStyle().alignSelf() = alignSelf; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { return node->getStyle().alignSelf(); @@ -640,8 +655,10 @@ YOGA_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetPositionType( const YGNodeRef node, const YGPositionType positionType) { - updateStyle( - node, &YGStyle::positionType, positionType); + if (node->getStyle().positionType() != positionType) { + node->getStyle().positionType() = positionType; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGPositionType YGNodeStyleGetPositionType(const YGNodeConstRef node) { @@ -651,7 +668,10 @@ YGNodeStyleGetPositionType(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetFlexWrap( const YGNodeRef node, const YGWrap flexWrap) { - updateStyle(node, &YGStyle::flexWrap, flexWrap); + if (node->getStyle().flexWrap() != flexWrap) { + node->getStyle().flexWrap() = flexWrap; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { return node->getStyle().flexWrap(); @@ -660,7 +680,10 @@ YOGA_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetOverflow( const YGNodeRef node, const YGOverflow overflow) { - updateStyle(node, &YGStyle::overflow, overflow); + if (node->getStyle().overflow() != overflow) { + node->getStyle().overflow() = overflow; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { return node->getStyle().overflow(); @@ -669,7 +692,10 @@ YOGA_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetDisplay( const YGNodeRef node, const YGDisplay display) { - updateStyle(node, &YGStyle::display, display); + if (node->getStyle().display() != display) { + node->getStyle().display() = display; + node->markDirtyAndPropogate(); + } } YOGA_EXPORT YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) { return node->getStyle().display(); From 198e99d30cd88dd1094078f47337718d7e227825 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 22 Nov 2019 04:28:49 -0800 Subject: [PATCH 04/87] Back out "not using templates for updating styles which are used via bitfield" Reviewed By: astreet Differential Revision: D18628090 fbshipit-source-id: 9d006534111f10ec25a0d56214792aeb96fbdef9 --- yoga/Yoga.cpp | 54 +++++++++++++-------------------------------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 1821c867..41de5119 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -582,10 +582,7 @@ void updateIndexedStyleProp( YOGA_EXPORT void YGNodeStyleSetDirection( const YGNodeRef node, const YGDirection value) { - if (node->getStyle().direction() != value) { - node->getStyle().direction() = value; - node->markDirtyAndPropogate(); - } + updateStyle(node, &YGStyle::direction, value); } YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { return node->getStyle().direction(); @@ -594,10 +591,8 @@ YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetFlexDirection( const YGNodeRef node, const YGFlexDirection flexDirection) { - if (node->getStyle().flexDirection() != flexDirection) { - node->getStyle().flexDirection() = flexDirection; - node->markDirtyAndPropogate(); - } + updateStyle( + node, &YGStyle::flexDirection, flexDirection); } YOGA_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { @@ -607,10 +602,8 @@ YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetJustifyContent( const YGNodeRef node, const YGJustify justifyContent) { - if (node->getStyle().justifyContent() != justifyContent) { - node->getStyle().justifyContent() = justifyContent; - node->markDirtyAndPropogate(); - } + updateStyle( + node, &YGStyle::justifyContent, justifyContent); } YOGA_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { return node->getStyle().justifyContent(); @@ -619,10 +612,8 @@ YOGA_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetAlignContent( const YGNodeRef node, const YGAlign alignContent) { - if (node->getStyle().alignContent() != alignContent) { - node->getStyle().alignContent() = alignContent; - node->markDirtyAndPropogate(); - } + updateStyle( + node, &YGStyle::alignContent, alignContent); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { return node->getStyle().alignContent(); @@ -631,10 +622,7 @@ YOGA_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetAlignItems( const YGNodeRef node, const YGAlign alignItems) { - if (node->getStyle().alignItems() != alignItems) { - node->getStyle().alignItems() = alignItems; - node->markDirtyAndPropogate(); - } + updateStyle(node, &YGStyle::alignItems, alignItems); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { return node->getStyle().alignItems(); @@ -643,10 +631,7 @@ YOGA_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetAlignSelf( const YGNodeRef node, const YGAlign alignSelf) { - if (node->getStyle().alignSelf() != alignSelf) { - node->getStyle().alignSelf() = alignSelf; - node->markDirtyAndPropogate(); - } + updateStyle(node, &YGStyle::alignSelf, alignSelf); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { return node->getStyle().alignSelf(); @@ -655,10 +640,8 @@ YOGA_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetPositionType( const YGNodeRef node, const YGPositionType positionType) { - if (node->getStyle().positionType() != positionType) { - node->getStyle().positionType() = positionType; - node->markDirtyAndPropogate(); - } + updateStyle( + node, &YGStyle::positionType, positionType); } YOGA_EXPORT YGPositionType YGNodeStyleGetPositionType(const YGNodeConstRef node) { @@ -668,10 +651,7 @@ YGNodeStyleGetPositionType(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetFlexWrap( const YGNodeRef node, const YGWrap flexWrap) { - if (node->getStyle().flexWrap() != flexWrap) { - node->getStyle().flexWrap() = flexWrap; - node->markDirtyAndPropogate(); - } + updateStyle(node, &YGStyle::flexWrap, flexWrap); } YOGA_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { return node->getStyle().flexWrap(); @@ -680,10 +660,7 @@ YOGA_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetOverflow( const YGNodeRef node, const YGOverflow overflow) { - if (node->getStyle().overflow() != overflow) { - node->getStyle().overflow() = overflow; - node->markDirtyAndPropogate(); - } + updateStyle(node, &YGStyle::overflow, overflow); } YOGA_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { return node->getStyle().overflow(); @@ -692,10 +669,7 @@ YOGA_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetDisplay( const YGNodeRef node, const YGDisplay display) { - if (node->getStyle().display() != display) { - node->getStyle().display() = display; - node->markDirtyAndPropogate(); - } + updateStyle(node, &YGStyle::display, display); } YOGA_EXPORT YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) { return node->getStyle().display(); From f4840a0148476fec8b1a58a078f0c37ebea0c979 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 22 Nov 2019 04:28:49 -0800 Subject: [PATCH 05/87] Added BitUtils Summary: Adds BitUtils to be used later instead of Bitfield.h ##Changelog: [Internal][Yoga] : Adds BitUtils to be used later instead of Bitfield.h Reviewed By: astreet Differential Revision: D18519609 fbshipit-source-id: 8353929543505a7d80d66281adb801d34372beed --- yoga/BitUtils.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 yoga/BitUtils.h diff --git a/yoga/BitUtils.h b/yoga/BitUtils.h new file mode 100644 index 00000000..1c32e9ec --- /dev/null +++ b/yoga/BitUtils.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include "YGEnums.h" + +namespace facebook { +namespace yoga { + +namespace detail { + +constexpr size_t log2ceilFn(size_t n) { + return n < 1 ? 0 : (1 + log2ceilFn(n / 2)); +} + +constexpr int mask(size_t bitWidth, size_t index) { + return ((1 << bitWidth) - 1) << index; +} + +// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL +template +constexpr size_t bitWidthFn() { + static_assert( + enums::count() > 0, "Enums must have at least one entries"); + return log2ceilFn(enums::count() - 1); +} + +template +constexpr Enum getEnumData(int flags, size_t index) { + return static_cast((flags & mask(bitWidthFn(), index)) >> index); +} + +template +void setEnumData(uint32_t& flags, size_t index, int newValue) { + flags = (flags & ~mask(bitWidthFn(), index)) | + ((newValue << index) & (mask(bitWidthFn(), index))); +} + +template +void setEnumData(uint8_t& flags, size_t index, int newValue) { + flags = (flags & ~mask(bitWidthFn(), index)) | + ((newValue << index) & (mask(bitWidthFn(), index))); +} + +constexpr bool getBooleanData(int flags, size_t index) { + return (flags >> index) & 1; +} + +inline void setBooleanData(uint8_t& flags, size_t index, bool value) { + if (value) { + flags |= 1 << index; + } else { + flags &= ~(1 << index); + } +} + +} // namespace detail +} // namespace yoga +} // namespace facebook From 9650c1903da021a5c397b79658176c54f36f10ce Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 22 Nov 2019 04:28:49 -0800 Subject: [PATCH 06/87] converts BitfieldTests to BitUtilsTest Summary: Use BitUtils for testing bit operations Reviewed By: astreet Differential Revision: D18596312 fbshipit-source-id: 83f93cd7f1f056b3f64070debbc452877b44ac7a --- tests/BitUtilsTest.cpp | 206 ++++++++++++++++++++++++++++++++++ tests/BitfieldTest.cpp | 244 ----------------------------------------- 2 files changed, 206 insertions(+), 244 deletions(-) create mode 100644 tests/BitUtilsTest.cpp delete mode 100644 tests/BitfieldTest.cpp diff --git a/tests/BitUtilsTest.cpp b/tests/BitUtilsTest.cpp new file mode 100644 index 00000000..d20ee307 --- /dev/null +++ b/tests/BitUtilsTest.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include +#include + +namespace facebook { +namespace yoga { + +TEST(BitUtils, one_boolean_defaults_to_false) { + constexpr uint8_t flags = 0; + + ASSERT_EQ(detail::getBooleanData(flags, 0), false); + static_assert( + detail::getBooleanData(flags, 0) == false, + "first boolean member must default to false"); +} + +TEST(BitUtils, one_boolean_can_be_initialized_to_true) { + constexpr uint8_t flags = 1; + + ASSERT_EQ(detail::getBooleanData(flags, 0), true); + static_assert( + detail::getBooleanData(flags, 0) == true, + "first boolean member must be initialized to true"); +} + +TEST(BitUtils, one_boolean_can_be_set_to_true) { + uint8_t flags = 0; + + detail::setBooleanData(flags, 0, true); + ASSERT_EQ(detail::getBooleanData(flags, 0), true); +} + +TEST(BitUtils, second_boolean_defaults_to_false) { + constexpr uint8_t flags = 0; + + ASSERT_EQ(detail::getBooleanData(flags, 1), false); + static_assert( + detail::getBooleanData(flags, 1) == false, + "second boolean member must default to false"); +} + +TEST(BitUtils, second_boolean_can_be_initialized_to_true) { + constexpr uint8_t flags = 2; + + ASSERT_EQ(detail::getBooleanData(flags, 0), false); + ASSERT_EQ(detail::getBooleanData(flags, 1), true); + static_assert( + detail::getBooleanData(flags, 0) == false, + "first boolean member must default to false"); + static_assert( + detail::getBooleanData(flags, 1) == true, + "second boolean member must be initialized to true"); +} + +TEST(BitUtils, second_boolean_can_be_set_to_true) { + uint8_t flags = 0; + + detail::setBooleanData(flags, 1, true); + ASSERT_EQ(detail::getBooleanData(flags, 0), false); + ASSERT_EQ(detail::getBooleanData(flags, 1), true); +} + +TEST(BitUtils, third_boolean_defaults_to_false) { + constexpr uint8_t flags = 0; + + ASSERT_EQ(detail::getBooleanData(flags, 2), false); + static_assert( + detail::getBooleanData(flags, 2) == false, + "second boolean member must default to false"); +} + +TEST(BitUtils, third_boolean_can_be_initialized_to_true) { + constexpr uint8_t flags = 4; + + ASSERT_EQ(detail::getBooleanData(flags, 0), false); + ASSERT_EQ(detail::getBooleanData(flags, 1), false); + ASSERT_EQ(detail::getBooleanData(flags, 2), true); + static_assert( + detail::getBooleanData(flags, 0) == false, + "first boolean member must default to false"); + static_assert( + detail::getBooleanData(flags, 1) == false, + "second boolean member must default to false"); + static_assert( + detail::getBooleanData(flags, 2) == true, + "second boolean member must be initialized to true"); +} + +TEST(BitUtils, third_boolean_can_be_set_to_true) { + uint8_t flags = 0; + + detail::setBooleanData(flags, 2, true); + ASSERT_EQ(detail::getBooleanData(flags, 0), false); + ASSERT_EQ(detail::getBooleanData(flags, 1), false); + ASSERT_EQ(detail::getBooleanData(flags, 2), true); +} + +TEST(BitUtils, setting_boolean_values_does_not_spill_over) { + uint8_t flags = 0; + + detail::setBooleanData(flags, 1, (bool) 7); + + ASSERT_EQ(detail::getBooleanData(flags, 0), false); + ASSERT_EQ(detail::getBooleanData(flags, 1), true); + ASSERT_EQ(detail::getBooleanData(flags, 2), false); +} + +TEST(BitUtils, first_enum_defaults_to_0) { + constexpr uint8_t flags = 0; + + ASSERT_EQ(detail::getEnumData(flags, 0), YGAlignAuto); + static_assert( + detail::getEnumData(flags, 0) == YGAlignAuto, + "first enum member must default to 0"); +} + +TEST(BitUtils, first_enum_can_be_set) { + uint8_t flags = 0; + + detail::setEnumData(flags, 0, YGAlignSpaceBetween); + + ASSERT_EQ(detail::getEnumData(flags, 0), YGAlignSpaceBetween); +} + +TEST(BitUtils, second_enum_defaults_to_0) { + constexpr uint8_t flags = 0; + static constexpr size_t alignOffset = 0; + static constexpr size_t edgeOffset = 3; + + ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); + ASSERT_EQ(detail::getEnumData(flags, edgeOffset), YGEdgeLeft); + static_assert( + detail::getEnumData(flags, alignOffset) == YGAlignAuto, + "first enum member must default to 0"); + static_assert( + detail::getEnumData(flags, edgeOffset) == YGEdgeLeft, + "second enum member must default to 0"); +} + +TEST(BitUtils, second_enum_can_be_set) { + uint8_t flags = 0; + static constexpr size_t alignOffset = 0; + static constexpr size_t edgeOffset = 3; + + detail::setEnumData(flags, edgeOffset, YGEdgeAll); + + ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); + ASSERT_EQ(detail::getEnumData(flags, edgeOffset), YGEdgeAll); +} + +TEST(BitUtils, third_enum_defaults_to_0) { + constexpr uint8_t flags = 0; + static constexpr size_t alignOffset = 0; + static constexpr size_t boolOffset = 3; + static constexpr size_t edgesOffset = 4; + + ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); + ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); + ASSERT_EQ(detail::getEnumData(flags, edgesOffset), YGEdgeLeft); + static_assert( + detail::getEnumData(flags, alignOffset) == YGAlignAuto, + "first enum member must default to 0"); + static_assert( + detail::getBooleanData(flags, boolOffset) == false, + "middle boolean member must default to false"); + static_assert( + detail::getEnumData(flags, edgesOffset) == YGEdgeLeft, + "last enum member must default to 0"); +} + +TEST(BitUtils, third_enum_can_be_set) { + uint8_t flags = 0; + static constexpr size_t alignOffset = 0; + static constexpr size_t boolOffset = 3; + static constexpr size_t edgesOffset = 4; + + detail::setEnumData(flags, edgesOffset, YGEdgeVertical); + + ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); + ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); + ASSERT_EQ(detail::getEnumData(flags, edgesOffset), YGEdgeVertical); +} + +TEST(BitUtils, setting_values_does_not_spill_over) { + uint8_t flags = 0; + static constexpr size_t alignOffset = 0; + static constexpr size_t edgesOffset = 3; + static constexpr size_t boolOffset = 7; + + detail::setEnumData(flags, edgesOffset, (YGEdge) 0xffffff); + + ASSERT_EQ(detail::getEnumData(flags, alignOffset), 0); + ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); + ASSERT_EQ(detail::getEnumData(flags, edgesOffset), 0xf); +} + +} // namespace yoga +} // namespace facebook diff --git a/tests/BitfieldTest.cpp b/tests/BitfieldTest.cpp deleted file mode 100644 index bb999c64..00000000 --- a/tests/BitfieldTest.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include - -#include -#include - -namespace facebook { -namespace yoga { - -TEST(Bitfield, one_boolean_defaults_to_false) { - constexpr auto bf = Bitfield{}; - - ASSERT_EQ(bf.at<0>(), false); - static_assert( - bf.at<0>() == false, "first boolean member must default to false"); -} - -TEST(Bitfield, one_boolean_can_be_initialized_to_true) { - constexpr auto bf = Bitfield{true}; - - ASSERT_EQ(bf.at<0>(), true); - static_assert( - bf.at<0>() == true, "first boolean member must be initialized to true"); -} - -TEST(Bitfield, one_boolean_can_be_set_to_true) { - auto bf = Bitfield{}; - - bf.at<0>() = true; - ASSERT_EQ(bf.at<0>(), true); -} - -TEST(Bitfield, second_boolean_defaults_to_false) { - constexpr auto bf = Bitfield{}; - - ASSERT_EQ(bf.at<1>(), false); - static_assert( - bf.at<1>() == false, "second boolean member must default to false"); -} - -TEST(Bitfield, second_boolean_can_be_initialized_to_true) { - constexpr auto bf = Bitfield{false, true}; - - ASSERT_EQ(bf.at<0>(), false); - ASSERT_EQ(bf.at<1>(), true); - static_assert( - bf.at<0>() == false, "first boolean member must default to false"); - static_assert( - bf.at<1>() == true, "second boolean member must be initialized to true"); -} - -TEST(Bitfield, second_boolean_can_be_set_to_true) { - auto bf = Bitfield{}; - - bf.at<1>() = true; - ASSERT_EQ(bf.at<0>(), false); - ASSERT_EQ(bf.at<1>(), true); -} - -TEST(Bitfield, third_boolean_defaults_to_false) { - constexpr auto bf = Bitfield{}; - - ASSERT_EQ(bf.at<2>(), false); - static_assert( - bf.at<2>() == false, "second boolean member must default to false"); -} - -TEST(Bitfield, third_boolean_can_be_initialized_to_true) { - constexpr auto bf = Bitfield{false, false, true}; - - ASSERT_EQ(bf.at<0>(), false); - ASSERT_EQ(bf.at<1>(), false); - ASSERT_EQ(bf.at<2>(), true); - static_assert( - bf.at<0>() == false, "first boolean member must default to false"); - static_assert( - bf.at<1>() == false, "second boolean member must default to false"); - static_assert( - bf.at<2>() == true, "second boolean member must be initialized to true"); -} - -TEST(Bitfield, third_boolean_can_be_set_to_true) { - auto bf = Bitfield{}; - - bf.at<2>() = true; - ASSERT_EQ(bf.at<0>(), false); - ASSERT_EQ(bf.at<1>(), false); - ASSERT_EQ(bf.at<2>(), true); -} - -TEST(Bitfield, initializing_boolean_values_does_not_spill_over) { - constexpr auto bf = - Bitfield{false, (bool) 7, false}; - - ASSERT_EQ(bf.at<0>(), false); - ASSERT_EQ(bf.at<1>(), true); - ASSERT_EQ(bf.at<2>(), false); - static_assert( - bf.at<0>() == false, "first boolean member must be initialized to false"); - static_assert( - bf.at<1>() == true, "second boolean member must be initialized to true"); - static_assert( - bf.at<2>() == false, "third boolean member must be initialized to false"); -} - -TEST(Bitfield, setting_boolean_values_does_not_spill_over) { - auto bf = Bitfield{}; - - bf.at<1>() = (bool) 7; - - ASSERT_EQ(bf.at<0>(), false); - ASSERT_EQ(bf.at<1>(), true); - ASSERT_EQ(bf.at<2>(), false); -} - -TEST(Bitfield, first_enum_defaults_to_0) { - constexpr auto bf = Bitfield{}; - - ASSERT_EQ(bf.at<0>(), YGAlignAuto); - static_assert( - bf.at<0>() == YGAlignAuto, "first enum member must default to 0"); -} - -TEST(Bitfield, first_enum_can_be_initialized) { - constexpr auto bf = Bitfield{YGAlignFlexEnd}; - - ASSERT_EQ(bf.at<0>(), YGAlignFlexEnd); - static_assert( - bf.at<0>() == YGAlignFlexEnd, - "first enum member must be initialized to YGAlignFlexEnd"); -} - -TEST(Bitfield, first_enum_can_be_set) { - auto bf = Bitfield{}; - - bf.at<0>() = YGAlignSpaceBetween; - - ASSERT_EQ(bf.at<0>(), YGAlignSpaceBetween); -} - -TEST(Bitfield, second_enum_defaults_to_0) { - constexpr auto bf = Bitfield{}; - - ASSERT_EQ(bf.at<0>(), YGAlignAuto); - ASSERT_EQ(bf.at<1>(), YGEdgeLeft); - static_assert( - bf.at<0>() == YGAlignAuto, "first enum member must default to 0"); - static_assert( - bf.at<1>() == YGEdgeLeft, "second enum member must default to 0"); -} - -TEST(Bitfield, second_enum_can_be_initialized) { - constexpr auto bf = - Bitfield{YGAlignAuto, YGEdgeAll}; - - ASSERT_EQ(bf.at<0>(), YGAlignAuto); - ASSERT_EQ(bf.at<1>(), YGEdgeAll); - static_assert( - bf.at<0>() == YGAlignAuto, "first enum member must default to 0"); - static_assert( - bf.at<1>() == YGEdgeAll, - "second enum member must be initialized to YGEdgeAll"); -} - -TEST(Bitfield, second_enum_can_be_set) { - auto bf = Bitfield{}; - - bf.at<1>() = YGEdgeAll; - - ASSERT_EQ(bf.at<0>(), YGAlignAuto); - ASSERT_EQ(bf.at<1>(), YGEdgeAll); -} - -TEST(Bitfield, third_enum_defaults_to_0) { - constexpr auto bf = Bitfield{}; - - ASSERT_EQ(bf.at<0>(), YGAlignAuto); - ASSERT_EQ(bf.at<1>(), false); - ASSERT_EQ(bf.at<2>(), YGEdgeLeft); - static_assert( - bf.at<0>() == YGAlignAuto, "first enum member must default to 0"); - static_assert( - bf.at<1>() == false, "middle boolean member must default to false"); - static_assert(bf.at<2>() == YGEdgeLeft, "last enum member must default to 0"); -} - -TEST(Bitfield, third_enum_can_be_initialized) { - constexpr auto bf = Bitfield{ - YGAlignAuto, false, YGEdgeVertical}; - - ASSERT_EQ(bf.at<0>(), YGAlignAuto); - ASSERT_EQ(bf.at<1>(), false); - ASSERT_EQ(bf.at<2>(), YGEdgeVertical); - static_assert( - bf.at<0>() == YGAlignAuto, "first enum member must default to 0"); - static_assert( - bf.at<1>() == false, "middle boolean member must default to false"); - static_assert( - bf.at<2>() == YGEdgeVertical, - "second enum member must be initialized to YGEdgeVertical"); -} - -TEST(Bitfield, third_enum_can_be_set) { - auto bf = Bitfield{}; - - bf.at<2>() = YGEdgeVertical; - - ASSERT_EQ(bf.at<0>(), YGAlignAuto); - ASSERT_EQ(bf.at<1>(), false); - ASSERT_EQ(bf.at<2>(), YGEdgeVertical); -} - -TEST(Bitfield, initializing_values_does_not_spill_over) { - constexpr auto bf = Bitfield{ - (YGAlign) 0, (YGEdge) 0xffffff, false}; - - ASSERT_EQ(bf.at<0>(), (YGAlign) 0); - ASSERT_EQ(bf.at<1>(), 0xf); - ASSERT_EQ(bf.at<2>(), false); - static_assert(bf.at<0>() == 0, "first enum member must be initialized to 0"); - static_assert( - bf.at<1>() == 0xf, "second member must be initialized to YGEdgeVertical"); - static_assert( - bf.at<2>() == false, "boolean member must be initialized to false"); -} - -TEST(Bitfield, setting_values_does_not_spill_over) { - auto bf = Bitfield{}; - - bf.at<1>() = (YGEdge) 0xffffff; - - ASSERT_EQ(bf.at<0>(), 0); - ASSERT_EQ(bf.at<1>(), 0xf); - ASSERT_EQ(bf.at<2>(), false); -} - -} // namespace yoga -} // namespace facebook From 9d2ca758fade8bcf743624b7ecff134cfa044cf0 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 22 Nov 2019 04:28:49 -0800 Subject: [PATCH 07/87] Remove Bitfield from YGStyle Summary: ##Changelog: [Internal][Yoga] Remove Bitfield from YGStyle Reviewed By: astreet Differential Revision: D18519614 fbshipit-source-id: 70f18bc679b62712d40d76bd793cf85906b067a1 --- yoga/YGStyle.h | 150 +++++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 61 deletions(-) diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index b066b346..9bfbc442 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -10,12 +10,12 @@ #include #include #include -#include "Bitfield.h" #include "CompactValue.h" #include "YGEnums.h" #include "YGFloatOptional.h" #include "Yoga-internal.h" #include "Yoga.h" +#include "BitUtils.h" class YOGA_EXPORT YGStyle { template @@ -27,6 +27,19 @@ public: using Dimensions = Values; using Edges = Values; + template + struct BitfieldRef { + YGStyle& style; + size_t offset; + operator T() const { + return facebook::yoga::detail::getEnumData(style.flags, offset); + } + BitfieldRef& operator=(T x) { + facebook::yoga::detail::setEnumData(style.flags, offset, x); + return *this; + } + }; + template struct Ref { YGStyle& style; @@ -60,43 +73,35 @@ public: CompactValue operator[](Idx idx) const { return (style.*Prop)[idx]; } }; - YGStyle() = default; + YGStyle() { + alignContent() = YGAlignFlexStart; + alignItems() = YGAlignStretch; + } ~YGStyle() = default; private: - static constexpr size_t directionIdx = 0; - static constexpr size_t flexDirectionIdx = 1; - static constexpr size_t justifyContentIdx = 2; - static constexpr size_t alignContentIdx = 3; - static constexpr size_t alignItemsIdx = 4; - static constexpr size_t alignSelfIdx = 5; - static constexpr size_t positionTypeIdx = 6; - static constexpr size_t flexWrapIdx = 7; - static constexpr size_t overflowIdx = 8; - static constexpr size_t displayIdx = 9; - using Flags = facebook::yoga::Bitfield< - uint32_t, - YGDirection, - YGFlexDirection, - YGJustify, - YGAlign, - YGAlign, - YGAlign, - YGPositionType, - YGWrap, - YGOverflow, - YGDisplay>; + static constexpr size_t directionOffset = 0; + static constexpr size_t flexdirectionOffset = + directionOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t justifyContentOffset = flexdirectionOffset + + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t alignContentOffset = + justifyContentOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t alignItemsOffset = + alignContentOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t alignSelfOffset = + alignItemsOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t positionTypeOffset = + alignSelfOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t flexWrapOffset = + positionTypeOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t overflowOffset = + flexWrapOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t displayOffset = + overflowOffset + facebook::yoga::detail::bitWidthFn(); + + uint32_t flags = 0; - Flags flags_ = {YGDirectionInherit, - YGFlexDirectionColumn, - YGJustifyFlexStart, - YGAlignFlexStart, - YGAlignStretch, - YGAlignAuto, - YGPositionTypeRelative, - YGWrapNoWrap, - YGOverflowVisible, - YGDisplayFlex}; YGFloatOptional flex_ = {}; YGFloatOptional flexGrow_ = {}; YGFloatOptional flexShrink_ = {}; @@ -115,45 +120,68 @@ public: // for library users needing a type using ValueRepr = std::remove_reference::type; - YGDirection direction() const { return flags_.at(); } - Flags::Ref direction() { return flags_.at(); } + YGDirection direction() const { + return facebook::yoga::detail::getEnumData( + flags, directionOffset); + } + BitfieldRef direction() { return {*this, directionOffset}; } YGFlexDirection flexDirection() const { - return flags_.at(); + return facebook::yoga::detail::getEnumData( + flags, flexdirectionOffset); } - Flags::Ref flexDirection() { - return flags_.at(); + BitfieldRef flexDirection() { + return {*this, flexdirectionOffset}; } - YGJustify justifyContent() const { return flags_.at(); } - Flags::Ref justifyContent() { - return flags_.at(); + YGJustify justifyContent() const { + return facebook::yoga::detail::getEnumData( + flags, justifyContentOffset); + } + BitfieldRef justifyContent() { + return {*this, justifyContentOffset}; } - YGAlign alignContent() const { return flags_.at(); } - Flags::Ref alignContent() { - return flags_.at(); + YGAlign alignContent() const { + return facebook::yoga::detail::getEnumData( + flags, alignContentOffset); + } + BitfieldRef alignContent() { return {*this, alignContentOffset}; } + + YGAlign alignItems() const { + return facebook::yoga::detail::getEnumData( + flags, alignItemsOffset); + } + BitfieldRef alignItems() { return {*this, alignItemsOffset}; } + + YGAlign alignSelf() const { + return facebook::yoga::detail::getEnumData(flags, alignSelfOffset); + } + BitfieldRef alignSelf() { return {*this, alignSelfOffset}; } + + YGPositionType positionType() const { + return facebook::yoga::detail::getEnumData( + flags, positionTypeOffset); + } + BitfieldRef positionType() { + return {*this, positionTypeOffset}; } - YGAlign alignItems() const { return flags_.at(); } - Flags::Ref alignItems() { return flags_.at(); } - - YGAlign alignSelf() const { return flags_.at(); } - Flags::Ref alignSelf() { return flags_.at(); } - - YGPositionType positionType() const { return flags_.at(); } - Flags::Ref positionType() { - return flags_.at(); + YGWrap flexWrap() const { + return facebook::yoga::detail::getEnumData(flags, flexWrapOffset); } + BitfieldRef flexWrap() { return {*this, flexWrapOffset}; } - YGWrap flexWrap() const { return flags_.at(); } - Flags::Ref flexWrap() { return flags_.at(); } + YGOverflow overflow() const { + return facebook::yoga::detail::getEnumData( + flags, overflowOffset); + } + BitfieldRef overflow() { return {*this, overflowOffset}; } - YGOverflow overflow() const { return flags_.at(); } - Flags::Ref overflow() { return flags_.at(); } - - YGDisplay display() const { return flags_.at(); } - Flags::Ref display() { return flags_.at(); } + YGDisplay display() const { + return facebook::yoga::detail::getEnumData(flags, displayOffset); + } + BitfieldRef display() { return {*this, displayOffset}; } YGFloatOptional flex() const { return flex_; } Ref flex() { return {*this}; } From f3498a29590105b4096035f16b0d3a35e27aa295 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 22 Nov 2019 04:28:49 -0800 Subject: [PATCH 08/87] Remove BItfield from YGLayout.h Summary: ##Changelog: [Internal][Yoga] Remove Bitfield from YGLayout Reviewed By: astreet Differential Revision: D18519623 fbshipit-source-id: 950b8cb1ca2cd0424b8d8748c4b71336b40fc15f --- yoga/YGLayout.h | 60 ++++++++++++++++++++++++++++++++----------------- yoga/YGNode.cpp | 8 +++---- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/yoga/YGLayout.h b/yoga/YGLayout.h index 658a31f2..30b8dd76 100644 --- a/yoga/YGLayout.h +++ b/yoga/YGLayout.h @@ -6,10 +6,12 @@ */ #pragma once -#include "Bitfield.h" +#include "BitUtils.h" #include "YGFloatOptional.h" #include "Yoga-internal.h" +using namespace facebook::yoga; + struct YGLayout { std::array position = {}; std::array dimensions = {{YGUndefined, YGUndefined}}; @@ -18,12 +20,14 @@ struct YGLayout { std::array padding = {}; private: - static constexpr size_t directionIdx = 0; - static constexpr size_t didUseLegacyFlagIdx = 1; - static constexpr size_t doesLegacyStretchFlagAffectsLayoutIdx = 2; - static constexpr size_t hadOverflowIdx = 3; - facebook::yoga::Bitfield flags_ = - {YGDirectionInherit, false, false, false}; + static constexpr size_t directionOffset = 0; + static constexpr size_t didUseLegacyFlagOffset = + directionOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t doesLegacyStretchFlagAffectsLayoutOffset = + didUseLegacyFlagOffset + 1; + static constexpr size_t hadOverflowOffset = + doesLegacyStretchFlagAffectsLayoutOffset + 1; + uint8_t flags = 0; public: uint32_t computedFlexBasisGeneration = 0; @@ -41,27 +45,41 @@ public: YGCachedMeasurement cachedLayout = YGCachedMeasurement(); - YGDirection direction() const { return flags_.at(); } - decltype(flags_)::Ref direction() { - return flags_.at(); + YGDirection direction() const { + return facebook::yoga::detail::getEnumData( + flags, directionOffset); } - bool didUseLegacyFlag() const { return flags_.at(); } - decltype(flags_)::Ref didUseLegacyFlag() { - return flags_.at(); + void setDirection(YGDirection direction) { + facebook::yoga::detail::setEnumData( + flags, directionOffset, direction); + } + + bool didUseLegacyFlag() const { + return facebook::yoga::detail::getBooleanData( + flags, didUseLegacyFlagOffset); + } + + void setDidUseLegacyFlag(bool val) { + facebook::yoga::detail::setBooleanData(flags, didUseLegacyFlagOffset, val); } bool doesLegacyStretchFlagAffectsLayout() const { - return flags_.at(); - } - decltype(flags_)::Ref - doesLegacyStretchFlagAffectsLayout() { - return flags_.at(); + return facebook::yoga::detail::getBooleanData( + flags, doesLegacyStretchFlagAffectsLayoutOffset); } - bool hadOverflow() const { return flags_.at(); } - decltype(flags_)::Ref hadOverflow() { - return flags_.at(); + void setDoesLegacyStretchFlagAffectsLayout(bool val) { + facebook::yoga::detail::setBooleanData( + flags, doesLegacyStretchFlagAffectsLayoutOffset, val); + } + + bool hadOverflow() const { + return facebook::yoga::detail::getBooleanData(flags, hadOverflowOffset); + } + void setHadOverflow(bool hadOverflow) { + facebook::yoga::detail::setBooleanData( + flags, hadOverflowOffset, hadOverflow); } bool operator==(YGLayout layout) const; diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 1d49b007..71d3a6db 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -232,7 +232,7 @@ void YGNode::removeChild(uint32_t index) { } void YGNode::setLayoutDirection(YGDirection direction) { - layout_.direction() = direction; + layout_.setDirection(direction); } void YGNode::setLayoutMargin(float margin, int index) { @@ -270,7 +270,7 @@ void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) { } void YGNode::setLayoutHadOverflow(bool hadOverflow) { - layout_.hadOverflow() = hadOverflow; + layout_.setHadOverflow(hadOverflow); } void YGNode::setLayoutDimension(float dimension, int index) { @@ -536,11 +536,11 @@ bool YGNode::didUseLegacyFlag() { void YGNode::setLayoutDoesLegacyFlagAffectsLayout( bool doesLegacyFlagAffectsLayout) { - layout_.doesLegacyStretchFlagAffectsLayout() = doesLegacyFlagAffectsLayout; + layout_.setDoesLegacyStretchFlagAffectsLayout(doesLegacyFlagAffectsLayout); } void YGNode::setLayoutDidUseLegacyFlag(bool didUseLegacyFlag) { - layout_.didUseLegacyFlag() = didUseLegacyFlag; + layout_.setDidUseLegacyFlag(didUseLegacyFlag); } bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const { From aeb9549af7fbfef5e43e3334a40687d5d885158e Mon Sep 17 00:00:00 2001 From: Sergey Ryabov Date: Fri, 22 Nov 2019 10:08:38 -0800 Subject: [PATCH 09/87] Fix javadocs Summary: Changelog: [Internal] Reviewed By: muraziz Differential Revision: D15538725 fbshipit-source-id: 5cf60f47b07ce355e40d5b064add1df980beed89 --- java/com/facebook/yoga/YogaNodeJNIBase.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/com/facebook/yoga/YogaNodeJNIBase.java b/java/com/facebook/yoga/YogaNodeJNIBase.java index 45d017c4..6372ddd7 100644 --- a/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -138,12 +138,12 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { } /** - * @returns the {@link YogaNode} that owns this {@link YogaNode}. - * The owner is used to identify the YogaTree that a {@link YogaNode} belongs - * to. + * The owner is used to identify the YogaTree that a {@link YogaNode} belongs to. * This method will return the parent of the {@link YogaNode} when the * {@link YogaNode} only belongs to one YogaTree or null when the * {@link YogaNode} is shared between two or more YogaTrees. + * + * @return the {@link YogaNode} that owns this {@link YogaNode}. */ @Nullable public YogaNodeJNIBase getOwner() { @@ -521,7 +521,7 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { * This is different than calling removeChildAt and addChildAt because this method ONLY replaces * the child in the mChildren datastructure. @DoNotStrip: called from JNI * - * @return the nativePointer of the newNode {@linl YogaNode} + * @return the nativePointer of the newNode {@link YogaNode} */ @DoNotStrip private final long replaceChild(YogaNodeJNIBase newNode, int childIndex) { From f7f134274c6b3673c5c9783aa661434950837e74 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Wed, 27 Nov 2019 14:16:42 -0800 Subject: [PATCH 10/87] Remove bitfield from YGNode.h Summary: ##Changelog: [Internal][Yoga] remove Bitfield from YGNode.h Reviewed By: astreet Differential Revision: D18519633 fbshipit-source-id: b5a7d8d5ee960c5618df382900c4ded3da0587a6 --- yoga/YGNode.cpp | 38 +++++++++++++++++++++----------------- yoga/YGNode.h | 43 ++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 71d3a6db..c15af8de 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -16,7 +16,7 @@ using facebook::yoga::detail::CompactValue; YGNode::YGNode(YGNode&& node) { context_ = node.context_; - flags_ = node.flags_; + flags = node.flags; measure_ = node.measure_; baseline_ = node.baseline_; print_ = node.print_; @@ -42,7 +42,7 @@ YGNode::YGNode(const YGNode& node, YGConfigRef config) : YGNode{node} { void YGNode::print(void* printContext) { if (print_.noContext != nullptr) { - if (flags_.at()) { + if (facebook::yoga::detail::getBooleanData(flags, printUsesContext_)) { print_.withContext(this, printContext); } else { print_.noContext(this); @@ -148,14 +148,14 @@ YGSize YGNode::measure( YGMeasureMode heightMode, void* layoutContext) { - return flags_.at() + return facebook::yoga::detail::getBooleanData(flags, measureUsesContext_) ? measure_.withContext( this, width, widthMode, height, heightMode, layoutContext) : measure_.noContext(this, width, widthMode, height, heightMode); } float YGNode::baseline(float width, float height, void* layoutContext) { - return flags_.at() + return facebook::yoga::detail::getBooleanData(flags, baselineUsesContext_) ? baseline_.withContext(this, width, height, layoutContext) : baseline_.noContext(this, width, height); } @@ -166,7 +166,7 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) { if (measureFunc.noContext == nullptr) { // TODO: t18095186 Move nodeType to opt-in function and mark appropriate // places in Litho - flags_.at() = YGNodeTypeDefault; + setNodeType(YGNodeTypeDefault); } else { YGAssertWithNode( this, @@ -182,14 +182,14 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) { } void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) { - flags_.at() = false; + facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, false); decltype(YGNode::measure_) m; m.noContext = measureFunc; setMeasureFunc(m); } YOGA_EXPORT void YGNode::setMeasureFunc(MeasureWithContextFn measureFunc) { - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, true); decltype(YGNode::measure_) m; m.withContext = measureFunc; setMeasureFunc(m); @@ -208,10 +208,10 @@ void YGNode::insertChild(YGNodeRef child, uint32_t index) { } void YGNode::setDirty(bool isDirty) { - if (isDirty == flags_.at()) { + if (isDirty == facebook::yoga::detail::getBooleanData(flags, isDirty_)) { return; } - flags_.at() = isDirty; + facebook::yoga::detail::setBooleanData(flags, isDirty_, isDirty); if (isDirty && dirtied_) { dirtied_(this); } @@ -351,7 +351,9 @@ YGValue YGNode::resolveFlexBasisPtr() const { return flexBasis; } if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) { - return flags_.at() ? YGValueAuto : YGValueZero; + return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) + ? YGValueAuto + : YGValueZero; } return YGValueAuto; } @@ -390,7 +392,7 @@ void YGNode::cloneChildrenIfNeeded(void* cloneContext) { } void YGNode::markDirtyAndPropogate() { - if (!flags_.at()) { + if (!facebook::yoga::detail::getBooleanData(flags, isDirty_)) { setDirty(true); setLayoutComputedFlexBasis(YGFloatOptional()); if (owner_) { @@ -400,7 +402,7 @@ void YGNode::markDirtyAndPropogate() { } void YGNode::markDirtyAndPropogateDownwards() { - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, isDirty_, true); for_each(children_.begin(), children_.end(), [](YGNodeRef childNode) { childNode->markDirtyAndPropogateDownwards(); }); @@ -427,12 +429,13 @@ float YGNode::resolveFlexShrink() const { if (!style_.flexShrink().isUndefined()) { return style_.flexShrink().unwrap(); } - if (!flags_.at() && !style_.flex().isUndefined() && - style_.flex().unwrap() < 0.0f) { + if (!facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) && + !style_.flex().isUndefined() && style_.flex().unwrap() < 0.0f) { return -style_.flex().unwrap(); } - return flags_.at() ? kWebDefaultFlexShrink - : kDefaultFlexShrink; + return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) + ? kWebDefaultFlexShrink + : kDefaultFlexShrink; } bool YGNode::isNodeFlexible() { @@ -577,7 +580,8 @@ void YGNode::reset() { clearChildren(); - auto webDefaults = flags_.at(); + auto webDefaults = + facebook::yoga::detail::getBooleanData(flags, useWebDefaults_); *this = YGNode{getConfig()}; if (webDefaults) { useWebDefaults(); diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 2967a1e2..95962e68 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -8,7 +8,7 @@ #pragma once #include #include -#include "Bitfield.h" +#include "BitUtils.h" #include "CompactValue.h" #include "YGConfig.h" #include "YGLayout.h" @@ -35,10 +35,7 @@ private: static constexpr size_t useWebDefaults_ = 7; void* context_ = nullptr; - using Flags = facebook::yoga:: - Bitfield; - Flags flags_ = - {true, false, false, YGNodeTypeDefault, false, false, false, false}; + uint8_t flags = 1; uint8_t reserved_ = 0; union { YGMeasureFunc noContext; @@ -70,7 +67,7 @@ private: void setBaselineFunc(decltype(baseline_)); void useWebDefaults() { - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, useWebDefaults_, true); style_.flexDirection() = YGFlexDirectionRow; style_.alignContent() = YGAlignStretch; } @@ -114,9 +111,13 @@ public: void print(void*); - bool getHasNewLayout() const { return flags_.at(); } + bool getHasNewLayout() const { + return facebook::yoga::detail::getBooleanData(flags, hasNewLayout_); + } - YGNodeType getNodeType() const { return flags_.at(); } + YGNodeType getNodeType() const { + return facebook::yoga::detail::getEnumData(flags, nodeType_); + } bool hasMeasureFunc() const noexcept { return measure_.noContext != nullptr; } @@ -142,7 +143,9 @@ public: uint32_t getLineIndex() const { return lineIndex_; } - bool isReferenceBaseline() { return flags_.at(); } + bool isReferenceBaseline() { + return facebook::yoga::detail::getBooleanData(flags, isReferenceBaseline_); + } // returns the YGNodeRef that owns this YGNode. An owner is used to identify // the YogaTree that a YGNode belongs to. This method will return the parent @@ -175,7 +178,9 @@ public: YGConfigRef getConfig() const { return config_; } - bool isDirty() const { return flags_.at(); } + bool isDirty() const { + return facebook::yoga::detail::getBooleanData(flags, isDirty_); + } std::array getResolvedDimensions() const { return resolvedDimensions_; @@ -223,19 +228,22 @@ public: void setPrintFunc(YGPrintFunc printFunc) { print_.noContext = printFunc; - flags_.at() = false; + facebook::yoga::detail::setBooleanData(flags, printUsesContext_, false); } void setPrintFunc(PrintWithContextFn printFunc) { print_.withContext = printFunc; - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, printUsesContext_, true); } void setPrintFunc(std::nullptr_t) { setPrintFunc(YGPrintFunc{nullptr}); } void setHasNewLayout(bool hasNewLayout) { - flags_.at() = hasNewLayout; + facebook::yoga::detail::setBooleanData(flags, hasNewLayout_, hasNewLayout); } - void setNodeType(YGNodeType nodeType) { flags_.at() = nodeType; } + void setNodeType(YGNodeType nodeType) { + return facebook::yoga::detail::setEnumData( + flags, nodeType_, nodeType); + } void setMeasureFunc(YGMeasureFunc measureFunc); void setMeasureFunc(MeasureWithContextFn); @@ -244,11 +252,11 @@ public: } void setBaselineFunc(YGBaselineFunc baseLineFunc) { - flags_.at() = false; + facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, false); baseline_.noContext = baseLineFunc; } void setBaselineFunc(BaselineWithContextFn baseLineFunc) { - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, true); baseline_.withContext = baseLineFunc; } void setBaselineFunc(std::nullptr_t) { @@ -264,7 +272,8 @@ public: void setLineIndex(uint32_t lineIndex) { lineIndex_ = lineIndex; } void setIsReferenceBaseline(bool isReferenceBaseline) { - flags_.at() = isReferenceBaseline; + facebook::yoga::detail::setBooleanData( + flags, isReferenceBaseline_, isReferenceBaseline); } void setOwner(YGNodeRef owner) { owner_ = owner; } From 015df9c5121a4fa1b24d70c3cd18ccecbcc2cb60 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Wed, 27 Nov 2019 14:16:42 -0800 Subject: [PATCH 11/87] Remove bitfield.h Summary: ##Changelog: [Internal][Yoga] Remove Bitfield.h Reviewed By: astreet Differential Revision: D18519647 fbshipit-source-id: b46fe585d3ef5f1da7d2726b2d9f759a649be121 --- yoga/Bitfield.h | 145 ------------------------------------------------ 1 file changed, 145 deletions(-) delete mode 100644 yoga/Bitfield.h diff --git a/yoga/Bitfield.h b/yoga/Bitfield.h deleted file mode 100644 index 02645961..00000000 --- a/yoga/Bitfield.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include - -namespace facebook { -namespace yoga { - -namespace detail { - -constexpr size_t log2ceil(size_t n) { - return n < 1 ? 0 : (1 + log2ceil(n / 2)); -} - -// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL -template -constexpr size_t bitWidth() { - static_assert( - enums::count() > 0, "Enums must have at least one entries"); - return log2ceil(enums::count() - 1); -} - -// Number of bits needed for a boolean -template <> -constexpr size_t bitWidth() { - return 1; -} - -template -struct BitTraits {}; - -template -struct BitTraits { - // Base cases - static constexpr size_t width(size_t) { return 0; } - static constexpr size_t shift(size_t) { return 0; } -}; - -template -struct BitTraits { - using Rest = BitTraits; - - static constexpr size_t width(size_t idx) { - return idx == 0 ? bitWidth() : Rest::width(idx - 1); - } - - static constexpr size_t shift(size_t idx) { - return idx == 0 ? Rest::width(0) + Rest::shift(0) : Rest::shift(idx - 1); - } - - static constexpr U mask(size_t idx) { - return ((U{1} << width(idx)) - 1) << shift(idx); - } -}; - -template -struct IndexedType { - using Type = typename IndexedType::Type; -}; - -template -struct IndexedType<0, T, Ts...> { - using Type = T; -}; - -} // namespace detail - -template -class Bitfield { - static_assert( - std::is_integral::value, - "Bitfield needs an integral storage type"); - static_assert( - std::is_unsigned::value, - "Bitfield needs an unsigned storage type"); - static_assert(sizeof...(Fields) > 0, "Bitfield needs at least one member"); - - using BitTraits = detail::BitTraits; - -#if !defined(_MSC_VER) || _MSC_VER > 1914 - static_assert( - BitTraits::shift(0) + BitTraits::width(0) <= - std::numeric_limits::digits, - "Specified storage type is too narrow to hold all types"); -#endif - - template - using TypeAt = typename detail::IndexedType::Type; - - template - static constexpr Storage initStorage(Value value, Values... values) { - return ((value << BitTraits::shift(Idx)) & BitTraits::mask(Idx)) | - initStorage(values...); - } - - template - static constexpr Storage initStorage() { - return Storage{0}; - } - - Storage storage_ = 0; - -public: - template - class Ref { - Bitfield& bitfield_; - - public: - Ref(Bitfield& bitfield) : bitfield_(bitfield) {} - Ref& operator=(TypeAt value) { - bitfield_.storage_ = (bitfield_.storage_ & ~BitTraits::mask(Idx)) | - ((value << BitTraits::shift(Idx)) & BitTraits::mask(Idx)); - return *this; - } - operator TypeAt() const { - return const_cast(bitfield_).at(); - } - }; - - constexpr Bitfield() = default; - constexpr Bitfield(Fields... values) : storage_{initStorage<0>(values...)} {} - - template - constexpr TypeAt at() const { - return static_cast>( - (storage_ & BitTraits::mask(Idx)) >> BitTraits::shift(Idx)); - } - - template - Ref at() { - return {*this}; - } -}; - -} // namespace yoga -} // namespace facebook From 67915b5905f0a23a76b283a543f83de5f279bbce Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Mon, 2 Dec 2019 05:21:56 -0800 Subject: [PATCH 12/87] Add YogaJniException class Summary: ## Changelog: [Internal][Yoga] Add YogaJniException class to be used later for jni exceptions Reviewed By: astreet Differential Revision: D18745609 fbshipit-source-id: 53503b54dbc59e9fe47f599dee6be9cb68134cb2 --- java/jni/YogaJniException.cpp | 49 +++++++++++++++++++++++++++++++++++ java/jni/YogaJniException.h | 38 +++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 java/jni/YogaJniException.cpp create mode 100644 java/jni/YogaJniException.h diff --git a/java/jni/YogaJniException.cpp b/java/jni/YogaJniException.cpp new file mode 100644 index 00000000..77aa3763 --- /dev/null +++ b/java/jni/YogaJniException.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include "YogaJniException.h" +#include "common.h" + +namespace facebook { +namespace yoga { +namespace vanillajni { + +YogaJniException::YogaJniException() { + jclass cl = getCurrentEnv()->FindClass("Ljava/lang/RuntimeException;"); + static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( + getCurrentEnv(), cl, "", "()V"); + auto throwable = getCurrentEnv()->NewObject(cl, methodId); + throwable_ = make_global_ref(static_cast(throwable)); +} + +YogaJniException::YogaJniException(jthrowable throwable) { + throwable_ = make_global_ref(throwable); +} + +YogaJniException::YogaJniException(YogaJniException&& rhs) + : throwable_(std::move(rhs.throwable_)) {} + +YogaJniException::YogaJniException(const YogaJniException& rhs) { + throwable_ = make_global_ref(rhs.throwable_.get()); +} + +YogaJniException::~YogaJniException() { + try { + throwable_.reset(); + } catch (...) { + std::terminate(); + } +} + +ScopedLocalRef YogaJniException::getThrowable() const noexcept { + return make_local_ref(getCurrentEnv(), throwable_.get()); +} +} // namespace vanillajni +} // namespace yoga +} // namespace facebook diff --git a/java/jni/YogaJniException.h b/java/jni/YogaJniException.h new file mode 100644 index 00000000..d333adf5 --- /dev/null +++ b/java/jni/YogaJniException.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include "common.h" + +namespace facebook { +namespace yoga { +namespace vanillajni { +/** + * This class wraps a Java exception (jthrowable) into a C++ exception; A global + * reference to Java exception (jthrowable) is made so that the exception object + * does not gets cleared before jni call completion + */ +class YogaJniException : public std::exception { +public: + YogaJniException(); + ~YogaJniException() override; + + explicit YogaJniException(jthrowable throwable); + + YogaJniException(YogaJniException&& rhs); + + YogaJniException(const YogaJniException& other); + + ScopedLocalRef getThrowable() const noexcept; + +private: + ScopedGlobalRef throwable_; +}; +} // namespace vanillajni +} // namespace yoga +} // namespace facebook From 073f49d0d0299a2aca0b890b202262e87629f4f0 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Mon, 2 Dec 2019 05:21:56 -0800 Subject: [PATCH 13/87] Use YogaJniException in jni call exception handling Summary: ##Changelog: [Internal][Yoga] Use YogaJniException in jni call exception handling Reviewed By: astreet Differential Revision: D18745615 fbshipit-source-id: 5fcf4c31f04fade94ef98a5349782ed3d43805b0 --- java/jni/YGJNIVanilla.cpp | 8 ++++++-- java/jni/corefunctions.cpp | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index 3ac88ac1..b9b590ac 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -15,6 +15,7 @@ #include #include #include +#include "YogaJniException.h" using namespace facebook::yoga::vanillajni; using facebook::yoga::detail::Log; @@ -372,8 +373,11 @@ static void jni_YGNodeCalculateLayoutJNI( YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer)), layoutContext); YGTransferLayoutOutputsRecursive(env, obj, root, layoutContext); - } catch (jthrowable throwable) { - env->Throw(throwable); + } catch (const YogaJniException& jniException) { + ScopedLocalRef throwable = jniException.getThrowable(); + if (throwable.get()) { + env->Throw(throwable.get()); + } } } diff --git a/java/jni/corefunctions.cpp b/java/jni/corefunctions.cpp index 04435724..4b03919c 100644 --- a/java/jni/corefunctions.cpp +++ b/java/jni/corefunctions.cpp @@ -7,6 +7,7 @@ #include "corefunctions.h" #include "macros.h" +#include "YogaJniException.h" namespace facebook { namespace yoga { @@ -72,7 +73,7 @@ void assertNoPendingJniException(JNIEnv* env) { logErrorMessageAndDie("Unable to get pending JNI exception."); } env->ExceptionClear(); - throw throwable; + throw YogaJniException(throwable); } } // namespace vanillajni From ac8eb111a955bdc0a37664e2a8d28c8b5701e130 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Mon, 2 Dec 2019 05:21:56 -0800 Subject: [PATCH 14/87] Add defensive check for result returned after JNI function calls Summary: Added method which checks if value(methodId, fieldId, class ...) returned by JNI functions (getMethod, getField, getClass ...) is valid or not and throw exception if they are not valid ##Changelog: [Internal][Yoga] Add defensive check for result returned after JNI calls Reviewed By: astreet Differential Revision: D18745718 fbshipit-source-id: 2af26eda15fbe7834e1c9b274deeed4f106274ab --- java/jni/common.cpp | 14 +++++++------- java/jni/corefunctions.cpp | 13 +++++++++++++ java/jni/corefunctions.h | 2 ++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/java/jni/common.cpp b/java/jni/common.cpp index f69ef94f..0cc37333 100644 --- a/java/jni/common.cpp +++ b/java/jni/common.cpp @@ -18,11 +18,11 @@ void registerNatives( size_t numMethods) { jclass clazz = env->FindClass(className); - assertNoPendingJniException(env); + assertNoPendingJniExceptionIf(env, !clazz); - env->RegisterNatives(clazz, methods, numMethods); + auto result = env->RegisterNatives(clazz, methods, numMethods); - assertNoPendingJniException(env); + assertNoPendingJniExceptionIf(env, result != JNI_OK); } jmethodID getStaticMethodId( @@ -32,7 +32,7 @@ jmethodID getStaticMethodId( const char* methodDescriptor) { jmethodID methodId = env->GetStaticMethodID(clazz, methodName, methodDescriptor); - assertNoPendingJniException(env); + assertNoPendingJniExceptionIf(env, !methodId); return methodId; } @@ -42,7 +42,7 @@ jmethodID getMethodId( const char* methodName, const char* methodDescriptor) { jmethodID methodId = env->GetMethodID(clazz, methodName, methodDescriptor); - assertNoPendingJniException(env); + assertNoPendingJniExceptionIf(env, !methodId); return methodId; } @@ -52,7 +52,7 @@ jfieldID getFieldId( const char* fieldName, const char* fieldSignature) { jfieldID fieldId = env->GetFieldID(clazz, fieldName, fieldSignature); - assertNoPendingJniException(env); + assertNoPendingJniExceptionIf(env, !fieldId); return fieldId; } @@ -83,7 +83,7 @@ callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...) { va_start(args, methodId); jobject result = env->CallStaticObjectMethodV(clazz, methodId, args); va_end(args); - assertNoPendingJniException(env); + assertNoPendingJniExceptionIf(env, !result); return make_local_ref(env, result); } diff --git a/java/jni/corefunctions.cpp b/java/jni/corefunctions.cpp index 4b03919c..8d522289 100644 --- a/java/jni/corefunctions.cpp +++ b/java/jni/corefunctions.cpp @@ -76,6 +76,19 @@ void assertNoPendingJniException(JNIEnv* env) { throw YogaJniException(throwable); } +void assertNoPendingJniExceptionIf(JNIEnv* env, bool condition) { + if (!condition) { + return; + } + + if (env->ExceptionCheck() == JNI_TRUE) { + assertNoPendingJniException(env); + return; + } + + throw YogaJniException(); +} + } // namespace vanillajni } // namespace yoga } // namespace facebook diff --git a/java/jni/corefunctions.h b/java/jni/corefunctions.h index 73d6cce4..18736dbb 100644 --- a/java/jni/corefunctions.h +++ b/java/jni/corefunctions.h @@ -47,6 +47,8 @@ void logErrorMessageAndDie(const char* message); */ void assertNoPendingJniException(JNIEnv* env); +void assertNoPendingJniExceptionIf(JNIEnv* env, bool condition); + } // namespace vanillajni } // namespace yoga } // namespace facebook From 089095f532bc6f6c585f345afa662b196837f596 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Tue, 3 Dec 2019 15:57:51 -0800 Subject: [PATCH 15/87] create global ref properly in YogaJNIException Summary: ##Changelog: [Internal][Yoga] create global ref properly in YogaJNIException Reviewed By: astreet Differential Revision: D18775982 fbshipit-source-id: ee529d6178d40b5f887fa1327fe156fa466f154f --- java/jni/YogaJniException.cpp | 11 +++++++---- java/jni/common.cpp | 10 ++++++++++ java/jni/common.h | 2 ++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/java/jni/YogaJniException.cpp b/java/jni/YogaJniException.cpp index 77aa3763..5d6bfbfe 100644 --- a/java/jni/YogaJniException.cpp +++ b/java/jni/YogaJniException.cpp @@ -19,18 +19,19 @@ YogaJniException::YogaJniException() { static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( getCurrentEnv(), cl, "", "()V"); auto throwable = getCurrentEnv()->NewObject(cl, methodId); - throwable_ = make_global_ref(static_cast(throwable)); + throwable_ = + newGlobalRef(getCurrentEnv(), static_cast(throwable)); } YogaJniException::YogaJniException(jthrowable throwable) { - throwable_ = make_global_ref(throwable); + throwable_ = newGlobalRef(getCurrentEnv(), throwable); } YogaJniException::YogaJniException(YogaJniException&& rhs) : throwable_(std::move(rhs.throwable_)) {} YogaJniException::YogaJniException(const YogaJniException& rhs) { - throwable_ = make_global_ref(rhs.throwable_.get()); + throwable_ = newGlobalRef(getCurrentEnv(), rhs.throwable_.get()); } YogaJniException::~YogaJniException() { @@ -42,7 +43,9 @@ YogaJniException::~YogaJniException() { } ScopedLocalRef YogaJniException::getThrowable() const noexcept { - return make_local_ref(getCurrentEnv(), throwable_.get()); + return make_local_ref( + getCurrentEnv(), + static_cast(getCurrentEnv()->NewLocalRef(throwable_.get()))); } } // namespace vanillajni } // namespace yoga diff --git a/java/jni/common.cpp b/java/jni/common.cpp index 0cc37333..143c695f 100644 --- a/java/jni/common.cpp +++ b/java/jni/common.cpp @@ -96,6 +96,16 @@ ScopedGlobalRef newGlobalRef(JNIEnv* env, jobject obj) { return make_global_ref(result); } + +ScopedGlobalRef newGlobalRef(JNIEnv* env, jthrowable obj) { + jthrowable result = static_cast(env->NewGlobalRef(obj)); + + if (!result) { + logErrorMessageAndDie("Could not obtain global reference from object"); + } + + return make_global_ref(result); +} } // namespace vanillajni } // namespace yoga } // namespace facebook diff --git a/java/jni/common.h b/java/jni/common.h index eebf8e9c..19eca6a4 100644 --- a/java/jni/common.h +++ b/java/jni/common.h @@ -69,6 +69,8 @@ callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...); * reference out of it. If any error happens, aborts the process. */ ScopedGlobalRef newGlobalRef(JNIEnv* env, jobject obj); + +ScopedGlobalRef newGlobalRef(JNIEnv* env, jthrowable obj); } // namespace vanillajni } // namespace yoga } // namespace facebook From 7f97e8b232881b71901cdc0d141a01ae5afbdef9 Mon Sep 17 00:00:00 2001 From: Amir Shalem Date: Wed, 4 Dec 2019 01:32:14 -0800 Subject: [PATCH 16/87] Allow redex to optimize more of yoga by removing unneeded @DoNotStrip marks Summary: There are multiple `DoNotStrip` in Yoga java binding, they aren't needed. ##Changelog: [Internal][Yoga] Allow redex to optimize more of yoga by removing unneeded DoNotStrip marks Reviewed By: SidharthGuglani Differential Revision: D17519844 fbshipit-source-id: 8b26800d720f34cae87754d85460abf88acbe713 --- java/com/facebook/yoga/YogaAlign.java | 3 --- java/com/facebook/yoga/YogaBaselineFunction.java | 4 ---- java/com/facebook/yoga/YogaDimension.java | 3 --- java/com/facebook/yoga/YogaDirection.java | 3 --- java/com/facebook/yoga/YogaDisplay.java | 3 --- java/com/facebook/yoga/YogaEdge.java | 3 --- java/com/facebook/yoga/YogaExperimentalFeature.java | 3 --- java/com/facebook/yoga/YogaFlexDirection.java | 3 --- java/com/facebook/yoga/YogaJustify.java | 3 --- java/com/facebook/yoga/YogaLogLevel.java | 1 + java/com/facebook/yoga/YogaMeasureFunction.java | 4 ---- java/com/facebook/yoga/YogaMeasureMode.java | 3 --- java/com/facebook/yoga/YogaNodeType.java | 3 --- java/com/facebook/yoga/YogaOverflow.java | 3 --- java/com/facebook/yoga/YogaPositionType.java | 3 --- java/com/facebook/yoga/YogaPrintOptions.java | 3 --- java/com/facebook/yoga/YogaStyleInputs.java | 3 --- java/com/facebook/yoga/YogaUnit.java | 3 --- java/com/facebook/yoga/YogaWrap.java | 3 --- 19 files changed, 1 insertion(+), 56 deletions(-) diff --git a/java/com/facebook/yoga/YogaAlign.java b/java/com/facebook/yoga/YogaAlign.java index afeaa500..82c6cbfb 100644 --- a/java/com/facebook/yoga/YogaAlign.java +++ b/java/com/facebook/yoga/YogaAlign.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaAlign { AUTO(0), FLEX_START(1), diff --git a/java/com/facebook/yoga/YogaBaselineFunction.java b/java/com/facebook/yoga/YogaBaselineFunction.java index a859aff4..dbd405c6 100644 --- a/java/com/facebook/yoga/YogaBaselineFunction.java +++ b/java/com/facebook/yoga/YogaBaselineFunction.java @@ -7,14 +7,10 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public interface YogaBaselineFunction { /** * Return the baseline of the node in points. When no baseline function is set the baseline * default to the computed height of the node. */ - @DoNotStrip float baseline(YogaNode node, float width, float height); } diff --git a/java/com/facebook/yoga/YogaDimension.java b/java/com/facebook/yoga/YogaDimension.java index 77ff6caa..cebcdc47 100644 --- a/java/com/facebook/yoga/YogaDimension.java +++ b/java/com/facebook/yoga/YogaDimension.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaDimension { WIDTH(0), HEIGHT(1); diff --git a/java/com/facebook/yoga/YogaDirection.java b/java/com/facebook/yoga/YogaDirection.java index e18ee9fa..4e75d303 100644 --- a/java/com/facebook/yoga/YogaDirection.java +++ b/java/com/facebook/yoga/YogaDirection.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaDirection { INHERIT(0), LTR(1), diff --git a/java/com/facebook/yoga/YogaDisplay.java b/java/com/facebook/yoga/YogaDisplay.java index e69d74b3..76cbfd77 100644 --- a/java/com/facebook/yoga/YogaDisplay.java +++ b/java/com/facebook/yoga/YogaDisplay.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaDisplay { FLEX(0), NONE(1); diff --git a/java/com/facebook/yoga/YogaEdge.java b/java/com/facebook/yoga/YogaEdge.java index e60ffd88..cba17934 100644 --- a/java/com/facebook/yoga/YogaEdge.java +++ b/java/com/facebook/yoga/YogaEdge.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaEdge { LEFT(0), TOP(1), diff --git a/java/com/facebook/yoga/YogaExperimentalFeature.java b/java/com/facebook/yoga/YogaExperimentalFeature.java index 8eb1bd2a..76525eab 100644 --- a/java/com/facebook/yoga/YogaExperimentalFeature.java +++ b/java/com/facebook/yoga/YogaExperimentalFeature.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaExperimentalFeature { WEB_FLEX_BASIS(0); diff --git a/java/com/facebook/yoga/YogaFlexDirection.java b/java/com/facebook/yoga/YogaFlexDirection.java index c844074e..83060e13 100644 --- a/java/com/facebook/yoga/YogaFlexDirection.java +++ b/java/com/facebook/yoga/YogaFlexDirection.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaFlexDirection { COLUMN(0), COLUMN_REVERSE(1), diff --git a/java/com/facebook/yoga/YogaJustify.java b/java/com/facebook/yoga/YogaJustify.java index 3508e17d..3d39015e 100644 --- a/java/com/facebook/yoga/YogaJustify.java +++ b/java/com/facebook/yoga/YogaJustify.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaJustify { FLEX_START(0), CENTER(1), diff --git a/java/com/facebook/yoga/YogaLogLevel.java b/java/com/facebook/yoga/YogaLogLevel.java index 57cb4aa0..f6a84023 100644 --- a/java/com/facebook/yoga/YogaLogLevel.java +++ b/java/com/facebook/yoga/YogaLogLevel.java @@ -28,6 +28,7 @@ public enum YogaLogLevel { return mIntValue; } + @DoNotStrip public static YogaLogLevel fromInt(int value) { switch (value) { case 0: return ERROR; diff --git a/java/com/facebook/yoga/YogaMeasureFunction.java b/java/com/facebook/yoga/YogaMeasureFunction.java index 335c4c79..8b8533ba 100644 --- a/java/com/facebook/yoga/YogaMeasureFunction.java +++ b/java/com/facebook/yoga/YogaMeasureFunction.java @@ -7,14 +7,10 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public interface YogaMeasureFunction { /** * Return a value created by YogaMeasureOutput.make(width, height); */ - @DoNotStrip long measure( YogaNode node, float width, diff --git a/java/com/facebook/yoga/YogaMeasureMode.java b/java/com/facebook/yoga/YogaMeasureMode.java index dbfd22c7..848d4aa7 100644 --- a/java/com/facebook/yoga/YogaMeasureMode.java +++ b/java/com/facebook/yoga/YogaMeasureMode.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaMeasureMode { UNDEFINED(0), EXACTLY(1), diff --git a/java/com/facebook/yoga/YogaNodeType.java b/java/com/facebook/yoga/YogaNodeType.java index 8d45d6ae..4386bf38 100644 --- a/java/com/facebook/yoga/YogaNodeType.java +++ b/java/com/facebook/yoga/YogaNodeType.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaNodeType { DEFAULT(0), TEXT(1); diff --git a/java/com/facebook/yoga/YogaOverflow.java b/java/com/facebook/yoga/YogaOverflow.java index 0e75106e..90c97881 100644 --- a/java/com/facebook/yoga/YogaOverflow.java +++ b/java/com/facebook/yoga/YogaOverflow.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaOverflow { VISIBLE(0), HIDDEN(1), diff --git a/java/com/facebook/yoga/YogaPositionType.java b/java/com/facebook/yoga/YogaPositionType.java index 23c2786f..00354f5c 100644 --- a/java/com/facebook/yoga/YogaPositionType.java +++ b/java/com/facebook/yoga/YogaPositionType.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaPositionType { RELATIVE(0), ABSOLUTE(1); diff --git a/java/com/facebook/yoga/YogaPrintOptions.java b/java/com/facebook/yoga/YogaPrintOptions.java index bc0c2de0..9a7f02ec 100644 --- a/java/com/facebook/yoga/YogaPrintOptions.java +++ b/java/com/facebook/yoga/YogaPrintOptions.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaPrintOptions { LAYOUT(1), STYLE(2), diff --git a/java/com/facebook/yoga/YogaStyleInputs.java b/java/com/facebook/yoga/YogaStyleInputs.java index dc26bad8..21ca2803 100644 --- a/java/com/facebook/yoga/YogaStyleInputs.java +++ b/java/com/facebook/yoga/YogaStyleInputs.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public class YogaStyleInputs { public static final short LAYOUT_DIRECTION = 0; public static final short FLEX_DIRECTION = 1; diff --git a/java/com/facebook/yoga/YogaUnit.java b/java/com/facebook/yoga/YogaUnit.java index d43c8ff1..5a7e5e66 100644 --- a/java/com/facebook/yoga/YogaUnit.java +++ b/java/com/facebook/yoga/YogaUnit.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaUnit { UNDEFINED(0), POINT(1), diff --git a/java/com/facebook/yoga/YogaWrap.java b/java/com/facebook/yoga/YogaWrap.java index 23af8a40..7ad00568 100644 --- a/java/com/facebook/yoga/YogaWrap.java +++ b/java/com/facebook/yoga/YogaWrap.java @@ -7,9 +7,6 @@ package com.facebook.yoga; -import com.facebook.proguard.annotations.DoNotStrip; - -@DoNotStrip public enum YogaWrap { NO_WRAP(0), WRAP(1), From e983c4a5ef32edfcda36b8197701196a56e610d5 Mon Sep 17 00:00:00 2001 From: Pasquale Anatriello Date: Thu, 30 Jan 2020 03:41:45 -0800 Subject: [PATCH 17/87] Swap child Yoga Summary: Changelog: [Internal] Expose the replaceChild Yoga call to Java Reviewed By: SidharthGuglani Differential Revision: D19497193 fbshipit-source-id: 153243cc1d8c23dcaf2c772ca794bd59a230f652 --- java/com/facebook/yoga/YogaNative.java | 1 + java/com/facebook/yoga/YogaNode.java | 2 + java/com/facebook/yoga/YogaNodeJNIBase.java | 87 +++++++++++++++------ java/jni/YGJNIVanilla.cpp | 11 +++ yoga/Yoga.cpp | 8 ++ yoga/Yoga.h | 5 ++ 6 files changed, 92 insertions(+), 22 deletions(-) diff --git a/java/com/facebook/yoga/YogaNative.java b/java/com/facebook/yoga/YogaNative.java index 334eaab5..3674b42f 100644 --- a/java/com/facebook/yoga/YogaNative.java +++ b/java/com/facebook/yoga/YogaNative.java @@ -34,6 +34,7 @@ public class YogaNative { static native void jni_YGNodeFreeJNI(long nativePointer); static native void jni_YGNodeResetJNI(long nativePointer); static native void jni_YGNodeInsertChildJNI(long nativePointer, long childPointer, int index); + static native void jni_YGNodeSwapChildJNI(long nativePointer, long childPointer, int index); static native void jni_YGNodeSetIsReferenceBaselineJNI(long nativePointer, boolean isReferenceBaseline); static native boolean jni_YGNodeIsReferenceBaselineJNI(long nativePointer); static native void jni_YGNodeClearChildrenJNI(long nativePointer); diff --git a/java/com/facebook/yoga/YogaNode.java b/java/com/facebook/yoga/YogaNode.java index baa0c517..9fc8bac9 100644 --- a/java/com/facebook/yoga/YogaNode.java +++ b/java/com/facebook/yoga/YogaNode.java @@ -214,4 +214,6 @@ public abstract class YogaNode { public abstract void print(); public abstract YogaNode cloneWithoutChildren(); + + public abstract YogaNode cloneWithChildren(); } diff --git a/java/com/facebook/yoga/YogaNodeJNIBase.java b/java/com/facebook/yoga/YogaNodeJNIBase.java index 6372ddd7..e20a5389 100644 --- a/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -39,11 +39,9 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { protected long mNativePointer; @Nullable private Object mData; - @DoNotStrip - private @Nullable float[] arr = null; + @DoNotStrip private @Nullable float[] arr = null; - @DoNotStrip - private int mLayoutDirection = 0; + @DoNotStrip private int mLayoutDirection = 0; private boolean mHasNewLayout = true; @@ -59,7 +57,7 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { } YogaNodeJNIBase(YogaConfig config) { - this(YogaNative.jni_YGNodeNewWithConfigJNI(((YogaConfigJNIBase)config).mNativePointer)); + this(YogaNative.jni_YGNodeNewWithConfigJNI(((YogaConfigJNIBase) config).mNativePointer)); } public void reset() { @@ -106,6 +104,32 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { return YogaNative.jni_YGNodeIsReferenceBaselineJNI(mNativePointer); } + public void swapChildAt(YogaNode newChild, int position) { + YogaNodeJNIBase child = (YogaNodeJNIBase) newChild; + mChildren.remove(position); + mChildren.add(position, child); + child.mOwner = this; + YogaNative.jni_YGNodeSwapChildJNI(mNativePointer, child.mNativePointer, position); + } + + @Override + public YogaNodeJNIBase cloneWithChildren() { + try { + YogaNodeJNIBase clonedYogaNode = (YogaNodeJNIBase) super.clone(); + long clonedNativePointer = YogaNative.jni_YGNodeCloneJNI(mNativePointer); + clonedYogaNode.mOwner = null; + clonedYogaNode.mNativePointer = clonedNativePointer; + for (int i = 0; i < clonedYogaNode.getChildCount(); i++) { + clonedYogaNode.swapChildAt(clonedYogaNode.getChildAt(i).cloneWithChildren(), i); + } + + return clonedYogaNode; + } catch (CloneNotSupportedException ex) { + // This class implements Cloneable, this should not happen + throw new RuntimeException(ex); + } + } + @Override public YogaNodeJNIBase cloneWithoutChildren() { try { @@ -138,10 +162,9 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { } /** - * The owner is used to identify the YogaTree that a {@link YogaNode} belongs to. - * This method will return the parent of the {@link YogaNode} when the - * {@link YogaNode} only belongs to one YogaTree or null when the - * {@link YogaNode} is shared between two or more YogaTrees. + * The owner is used to identify the YogaTree that a {@link YogaNode} belongs to. This method will + * return the parent of the {@link YogaNode} when the {@link YogaNode} only belongs to one + * YogaTree or null when the {@link YogaNode} is shared between two or more YogaTrees. * * @return the {@link YogaNode} that owns this {@link YogaNode}. */ @@ -168,7 +191,7 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { ArrayList n = new ArrayList<>(); n.add(this); for (int i = 0; i < n.size(); ++i) { - List children = n.get(i).mChildren; + List children = n.get(i).mChildren; if (children != null) { n.addAll(children); } @@ -509,8 +532,8 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { } /** - * Use the set logger (defaults to adb log) to print out the styles, children, and computed - * layout of the tree rooted at this node. + * Use the set logger (defaults to adb log) to print out the styles, children, and computed layout + * of the tree rooted at this node. */ public void print() { YogaNative.jni_YGNodePrintJNI(mNativePointer); @@ -559,7 +582,9 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { } public boolean getDoesLegacyStretchFlagAffectsLayout() { - return arr != null && (((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & DOES_LEGACY_STRETCH_BEHAVIOUR) == DOES_LEGACY_STRETCH_BEHAVIOUR); + return arr != null + && (((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & DOES_LEGACY_STRETCH_BEHAVIOUR) + == DOES_LEGACY_STRETCH_BEHAVIOUR); } @Override @@ -575,9 +600,13 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { case BOTTOM: return arr[LAYOUT_MARGIN_START_INDEX + 3]; case START: - return getLayoutDirection() == YogaDirection.RTL ? arr[LAYOUT_MARGIN_START_INDEX + 2] : arr[LAYOUT_MARGIN_START_INDEX]; + return getLayoutDirection() == YogaDirection.RTL + ? arr[LAYOUT_MARGIN_START_INDEX + 2] + : arr[LAYOUT_MARGIN_START_INDEX]; case END: - return getLayoutDirection() == YogaDirection.RTL ? arr[LAYOUT_MARGIN_START_INDEX] : arr[LAYOUT_MARGIN_START_INDEX + 2]; + return getLayoutDirection() == YogaDirection.RTL + ? arr[LAYOUT_MARGIN_START_INDEX] + : arr[LAYOUT_MARGIN_START_INDEX + 2]; default: throw new IllegalArgumentException("Cannot get layout margins of multi-edge shorthands"); } @@ -589,7 +618,9 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { @Override public float getLayoutPadding(YogaEdge edge) { if (arr != null && ((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & PADDING) == PADDING) { - int paddingStartIndex = LAYOUT_PADDING_START_INDEX - ((((int)arr[LAYOUT_EDGE_SET_FLAG_INDEX] & MARGIN) == MARGIN) ? 0 : 4); + int paddingStartIndex = + LAYOUT_PADDING_START_INDEX + - ((((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & MARGIN) == MARGIN) ? 0 : 4); switch (edge) { case LEFT: return arr[paddingStartIndex]; @@ -600,9 +631,13 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { case BOTTOM: return arr[paddingStartIndex + 3]; case START: - return getLayoutDirection() == YogaDirection.RTL ? arr[paddingStartIndex + 2] : arr[paddingStartIndex]; + return getLayoutDirection() == YogaDirection.RTL + ? arr[paddingStartIndex + 2] + : arr[paddingStartIndex]; case END: - return getLayoutDirection() == YogaDirection.RTL ? arr[paddingStartIndex] : arr[paddingStartIndex + 2]; + return getLayoutDirection() == YogaDirection.RTL + ? arr[paddingStartIndex] + : arr[paddingStartIndex + 2]; default: throw new IllegalArgumentException("Cannot get layout paddings of multi-edge shorthands"); } @@ -614,7 +649,10 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { @Override public float getLayoutBorder(YogaEdge edge) { if (arr != null && ((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & BORDER) == BORDER) { - int borderStartIndex = LAYOUT_BORDER_START_INDEX - ((((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & MARGIN) == MARGIN) ? 0 : 4) - ((((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & PADDING) == PADDING) ? 0 : 4); + int borderStartIndex = + LAYOUT_BORDER_START_INDEX + - ((((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & MARGIN) == MARGIN) ? 0 : 4) + - ((((int) arr[LAYOUT_EDGE_SET_FLAG_INDEX] & PADDING) == PADDING) ? 0 : 4); switch (edge) { case LEFT: return arr[borderStartIndex]; @@ -625,9 +663,13 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { case BOTTOM: return arr[borderStartIndex + 3]; case START: - return getLayoutDirection() == YogaDirection.RTL ? arr[borderStartIndex + 2] : arr[borderStartIndex]; + return getLayoutDirection() == YogaDirection.RTL + ? arr[borderStartIndex + 2] + : arr[borderStartIndex]; case END: - return getLayoutDirection() == YogaDirection.RTL ? arr[borderStartIndex] : arr[borderStartIndex + 2]; + return getLayoutDirection() == YogaDirection.RTL + ? arr[borderStartIndex] + : arr[borderStartIndex + 2]; default: throw new IllegalArgumentException("Cannot get layout border of multi-edge shorthands"); } @@ -638,7 +680,8 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { @Override public YogaDirection getLayoutDirection() { - return YogaDirection.fromInt(arr != null ? (int) arr[LAYOUT_DIRECTION_INDEX] : mLayoutDirection); + return YogaDirection.fromInt( + arr != null ? (int) arr[LAYOUT_DIRECTION_INDEX] : mLayoutDirection); } @Override diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index b9b590ac..6e66c06e 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -225,6 +225,16 @@ static void jni_YGNodeInsertChildJNI( _jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index); } +static void jni_YGNodeSwapChildJNI( + JNIEnv* env, + jobject obj, + jlong nativePointer, + jlong childPointer, + jint index) { + YGNodeSwapChild( + _jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index); +} + static void jni_YGNodeSetIsReferenceBaselineJNI( JNIEnv* env, jobject obj, @@ -754,6 +764,7 @@ static JNINativeMethod methods[] = { {"jni_YGNodeFreeJNI", "(J)V", (void*) jni_YGNodeFreeJNI}, {"jni_YGNodeResetJNI", "(J)V", (void*) jni_YGNodeResetJNI}, {"jni_YGNodeInsertChildJNI", "(JJI)V", (void*) jni_YGNodeInsertChildJNI}, + {"jni_YGNodeSwapChildJNI", "(JJI)V", (void*) jni_YGNodeSwapChildJNI}, {"jni_YGNodeSetIsReferenceBaselineJNI", "(JZ)V", (void*) jni_YGNodeSetIsReferenceBaselineJNI}, diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 41de5119..e30a36b7 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -386,6 +386,14 @@ YOGA_EXPORT void YGNodeInsertChild( owner->markDirtyAndPropogate(); } +YOGA_EXPORT void YGNodeSwapChild( + const YGNodeRef owner, + const YGNodeRef child, + const uint32_t index) { + owner->replaceChild(child, index); + child->setOwner(owner); +} + YOGA_EXPORT void YGNodeRemoveChild( const YGNodeRef owner, const YGNodeRef excludedChild) { diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 68ed0a62..2fe60a41 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -69,6 +69,11 @@ WIN_EXPORT void YGNodeInsertChild( YGNodeRef child, uint32_t index); +WIN_EXPORT void YGNodeSwapChild( + YGNodeRef node, + YGNodeRef child, + uint32_t index); + WIN_EXPORT void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child); WIN_EXPORT void YGNodeRemoveAllChildren(YGNodeRef node); WIN_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index); From a1278cee05f5c533afe81e7c28e1bed916887d30 Mon Sep 17 00:00:00 2001 From: Christoph Purrer Date: Wed, 5 Feb 2020 13:35:21 -0800 Subject: [PATCH 18/87] Make YGValue.h compile with Clang on Windows Summary: - We use a fork of Microsoft's react-native-windows which uses a fork of Facebook's react-native - YGValue.h does not compile with Clang on Windows - This change should fix that - I want to put the change here so that it bubbles back to our fork > https://our.intern.facebook.com/intern/diff/D19656093/ #Changelog: [General][Fixed] Make YGValue.h compile with Clang on Windows Reviewed By: SidharthGuglani Differential Revision: D19717489 fbshipit-source-id: ad867ecaf910bb64a777a06c656a1867bb15484b --- yoga/YGValue.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/yoga/YGValue.h b/yoga/YGValue.h index aaa10c3f..a2000978 100644 --- a/yoga/YGValue.h +++ b/yoga/YGValue.h @@ -11,6 +11,13 @@ #include "YGEnums.h" #include "YGMacros.h" +#if defined(_MSC_VER) && defined(__clang__) +#define COMPILING_WITH_CLANG_ON_WINDOWS +#endif +#if defined(COMPILING_WITH_CLANG_ON_WINDOWS) +#include +constexpr float YGUndefined = std::numeric_limits::quiet_NaN(); +#else YG_EXTERN_C_BEGIN // Not defined in MSVC++ @@ -20,6 +27,7 @@ static const uint32_t __nan = 0x7fc00000; #endif #define YGUndefined NAN +#endif typedef struct YGValue { float value; @@ -30,7 +38,10 @@ YOGA_EXPORT extern const YGValue YGValueAuto; YOGA_EXPORT extern const YGValue YGValueUndefined; YOGA_EXPORT extern const YGValue YGValueZero; +#if !defined(COMPILING_WITH_CLANG_ON_WINDOWS) YG_EXTERN_C_END +#endif +#undef COMPILING_WITH_CLANG_ON_WINDOWS #ifdef __cplusplus From bfc3b2f86f86f0b4cd1616a3450e249a8e6c9313 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Tue, 18 Feb 2020 08:09:53 -0800 Subject: [PATCH 19/87] fix lint errors Summary: Changelog: [Internal][Yoga] Fixed lint errors ```arc lint --apply-patches --take CLANGFORMAT --paths-cmd 'hg files xplat/yoga' ``` Added .clang-tidy file Reviewed By: zertosh Differential Revision: D19948702 fbshipit-source-id: f77a16d6f2c532267597a84a9caded0aae68c3aa --- YogaKit/Source/UIView+Yoga.h | 15 +- YogaKit/Source/UIView+Yoga.m | 18 +- YogaKit/Source/YGLayout+Private.h | 6 +- YogaKit/Source/YGLayout.h | 154 +++--- YogaKit/Source/YGLayout.m | 448 +++++++++--------- YogaKit/Tests/YogaKitTests.m | 351 +++++++------- .../YogaKitSample/ViewController.m | 64 ++- csharp/Yoga/YGInterop.cpp | 11 +- csharp/Yoga/YGInterop.h | 9 +- csharp/Yoga/dllmain.cpp | 3 +- csharp/Yoga/targetver.h | 5 +- java/jni/ScopedGlobalRef.h | 8 +- java/jni/ScopedLocalRef.h | 8 +- java/jni/common.cpp | 7 +- java/jni/common.h | 7 +- javascript/sources/Size.hh | 4 +- javascript/sources/Value.hh | 4 +- 17 files changed, 568 insertions(+), 554 deletions(-) diff --git a/YogaKit/Source/UIView+Yoga.h b/YogaKit/Source/UIView+Yoga.h index cac23385..4c85dcc4 100644 --- a/YogaKit/Source/UIView+Yoga.h +++ b/YogaKit/Source/UIView+Yoga.h @@ -5,28 +5,29 @@ * LICENSE file in the root directory of this source tree. */ -#import "YGLayout.h" #import +#import "YGLayout.h" NS_ASSUME_NONNULL_BEGIN -typedef void (^YGLayoutConfigurationBlock)(YGLayout *layout); +typedef void (^YGLayoutConfigurationBlock)(YGLayout* layout); @interface UIView (Yoga) /** The YGLayout that is attached to this view. It is lazily created. */ -@property (nonatomic, readonly, strong) YGLayout *yoga; +@property(nonatomic, readonly, strong) YGLayout* yoga; /** Indicates whether or not Yoga is enabled */ -@property (nonatomic, readonly, assign) BOOL isYogaEnabled; +@property(nonatomic, readonly, assign) BOOL isYogaEnabled; /** - In ObjC land, every time you access `view.yoga.*` you are adding another `objc_msgSend` - to your code. If you plan on making multiple changes to YGLayout, it's more performant - to use this method, which uses a single objc_msgSend call. + In ObjC land, every time you access `view.yoga.*` you are adding another + `objc_msgSend` to your code. If you plan on making multiple changes to + YGLayout, it's more performant to use this method, which uses a single + objc_msgSend call. */ - (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block NS_SWIFT_NAME(configureLayout(block:)); diff --git a/YogaKit/Source/UIView+Yoga.m b/YogaKit/Source/UIView+Yoga.m index ba133919..e472c9c7 100644 --- a/YogaKit/Source/UIView+Yoga.m +++ b/YogaKit/Source/UIView+Yoga.m @@ -5,32 +5,30 @@ * LICENSE file in the root directory of this source tree. */ +#import #import "UIView+Yoga.h" #import "YGLayout+Private.h" -#import -static const void *kYGYogaAssociatedKey = &kYGYogaAssociatedKey; +static const void* kYGYogaAssociatedKey = &kYGYogaAssociatedKey; @implementation UIView (YogaKit) -- (YGLayout *)yoga -{ - YGLayout *yoga = objc_getAssociatedObject(self, kYGYogaAssociatedKey); +- (YGLayout*)yoga { + YGLayout* yoga = objc_getAssociatedObject(self, kYGYogaAssociatedKey); if (!yoga) { yoga = [[YGLayout alloc] initWithView:self]; - objc_setAssociatedObject(self, kYGYogaAssociatedKey, yoga, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject( + self, kYGYogaAssociatedKey, yoga, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } return yoga; } -- (BOOL)isYogaEnabled -{ +- (BOOL)isYogaEnabled { return objc_getAssociatedObject(self, kYGYogaAssociatedKey) != nil; } -- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block -{ +- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block { if (block != nil) { block(self.yoga); } diff --git a/YogaKit/Source/YGLayout+Private.h b/YogaKit/Source/YGLayout+Private.h index 00ab40f5..0588d950 100644 --- a/YogaKit/Source/YGLayout+Private.h +++ b/YogaKit/Source/YGLayout+Private.h @@ -5,13 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -#import "YGLayout.h" #import +#import "YGLayout.h" @interface YGLayout () -@property (nonatomic, assign, readonly) YGNodeRef node; +@property(nonatomic, assign, readonly) YGNodeRef node; -- (instancetype)initWithView:(UIView *)view; +- (instancetype)initWithView:(UIView*)view; @end diff --git a/YogaKit/Source/YGLayout.h b/YogaKit/Source/YGLayout.h index 19f3982b..5a60f95e 100644 --- a/YogaKit/Source/YGLayout.h +++ b/YogaKit/Source/YGLayout.h @@ -7,15 +7,15 @@ #import #import -#import #import +#import YG_EXTERN_C_BEGIN -extern YGValue YGPointValue(CGFloat value) - NS_SWIFT_UNAVAILABLE("Use the swift Int and FloatingPoint extensions instead"); -extern YGValue YGPercentValue(CGFloat value) - NS_SWIFT_UNAVAILABLE("Use the swift Int and FloatingPoint extensions instead"); +extern YGValue YGPointValue(CGFloat value) NS_SWIFT_UNAVAILABLE( + "Use the swift Int and FloatingPoint extensions instead"); +extern YGValue YGPercentValue(CGFloat value) NS_SWIFT_UNAVAILABLE( + "Use the swift Int and FloatingPoint extensions instead"); YG_EXTERN_C_END @@ -44,103 +44,107 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) { The property that decides if we should include this view when calculating layout. Defaults to YES. */ -@property (nonatomic, readwrite, assign, setter=setIncludedInLayout:) BOOL isIncludedInLayout; +@property(nonatomic, readwrite, assign, setter=setIncludedInLayout:) + BOOL isIncludedInLayout; /** - The property that decides during layout/sizing whether or not styling properties should be applied. - Defaults to NO. + The property that decides during layout/sizing whether or not styling + properties should be applied. Defaults to NO. */ -@property (nonatomic, readwrite, assign, setter=setEnabled:) BOOL isEnabled; +@property(nonatomic, readwrite, assign, setter=setEnabled:) BOOL isEnabled; -@property (nonatomic, readwrite, assign) YGDirection direction; -@property (nonatomic, readwrite, assign) YGFlexDirection flexDirection; -@property (nonatomic, readwrite, assign) YGJustify justifyContent; -@property (nonatomic, readwrite, assign) YGAlign alignContent; -@property (nonatomic, readwrite, assign) YGAlign alignItems; -@property (nonatomic, readwrite, assign) YGAlign alignSelf; -@property (nonatomic, readwrite, assign) YGPositionType position; -@property (nonatomic, readwrite, assign) YGWrap flexWrap; -@property (nonatomic, readwrite, assign) YGOverflow overflow; -@property (nonatomic, readwrite, assign) YGDisplay display; +@property(nonatomic, readwrite, assign) YGDirection direction; +@property(nonatomic, readwrite, assign) YGFlexDirection flexDirection; +@property(nonatomic, readwrite, assign) YGJustify justifyContent; +@property(nonatomic, readwrite, assign) YGAlign alignContent; +@property(nonatomic, readwrite, assign) YGAlign alignItems; +@property(nonatomic, readwrite, assign) YGAlign alignSelf; +@property(nonatomic, readwrite, assign) YGPositionType position; +@property(nonatomic, readwrite, assign) YGWrap flexWrap; +@property(nonatomic, readwrite, assign) YGOverflow overflow; +@property(nonatomic, readwrite, assign) YGDisplay display; -@property (nonatomic, readwrite, assign) CGFloat flex; -@property (nonatomic, readwrite, assign) CGFloat flexGrow; -@property (nonatomic, readwrite, assign) CGFloat flexShrink; -@property (nonatomic, readwrite, assign) YGValue flexBasis; +@property(nonatomic, readwrite, assign) CGFloat flex; +@property(nonatomic, readwrite, assign) CGFloat flexGrow; +@property(nonatomic, readwrite, assign) CGFloat flexShrink; +@property(nonatomic, readwrite, assign) YGValue flexBasis; -@property (nonatomic, readwrite, assign) YGValue left; -@property (nonatomic, readwrite, assign) YGValue top; -@property (nonatomic, readwrite, assign) YGValue right; -@property (nonatomic, readwrite, assign) YGValue bottom; -@property (nonatomic, readwrite, assign) YGValue start; -@property (nonatomic, readwrite, assign) YGValue end; +@property(nonatomic, readwrite, assign) YGValue left; +@property(nonatomic, readwrite, assign) YGValue top; +@property(nonatomic, readwrite, assign) YGValue right; +@property(nonatomic, readwrite, assign) YGValue bottom; +@property(nonatomic, readwrite, assign) YGValue start; +@property(nonatomic, readwrite, assign) YGValue end; -@property (nonatomic, readwrite, assign) YGValue marginLeft; -@property (nonatomic, readwrite, assign) YGValue marginTop; -@property (nonatomic, readwrite, assign) YGValue marginRight; -@property (nonatomic, readwrite, assign) YGValue marginBottom; -@property (nonatomic, readwrite, assign) YGValue marginStart; -@property (nonatomic, readwrite, assign) YGValue marginEnd; -@property (nonatomic, readwrite, assign) YGValue marginHorizontal; -@property (nonatomic, readwrite, assign) YGValue marginVertical; -@property (nonatomic, readwrite, assign) YGValue margin; +@property(nonatomic, readwrite, assign) YGValue marginLeft; +@property(nonatomic, readwrite, assign) YGValue marginTop; +@property(nonatomic, readwrite, assign) YGValue marginRight; +@property(nonatomic, readwrite, assign) YGValue marginBottom; +@property(nonatomic, readwrite, assign) YGValue marginStart; +@property(nonatomic, readwrite, assign) YGValue marginEnd; +@property(nonatomic, readwrite, assign) YGValue marginHorizontal; +@property(nonatomic, readwrite, assign) YGValue marginVertical; +@property(nonatomic, readwrite, assign) YGValue margin; -@property (nonatomic, readwrite, assign) YGValue paddingLeft; -@property (nonatomic, readwrite, assign) YGValue paddingTop; -@property (nonatomic, readwrite, assign) YGValue paddingRight; -@property (nonatomic, readwrite, assign) YGValue paddingBottom; -@property (nonatomic, readwrite, assign) YGValue paddingStart; -@property (nonatomic, readwrite, assign) YGValue paddingEnd; -@property (nonatomic, readwrite, assign) YGValue paddingHorizontal; -@property (nonatomic, readwrite, assign) YGValue paddingVertical; -@property (nonatomic, readwrite, assign) YGValue padding; +@property(nonatomic, readwrite, assign) YGValue paddingLeft; +@property(nonatomic, readwrite, assign) YGValue paddingTop; +@property(nonatomic, readwrite, assign) YGValue paddingRight; +@property(nonatomic, readwrite, assign) YGValue paddingBottom; +@property(nonatomic, readwrite, assign) YGValue paddingStart; +@property(nonatomic, readwrite, assign) YGValue paddingEnd; +@property(nonatomic, readwrite, assign) YGValue paddingHorizontal; +@property(nonatomic, readwrite, assign) YGValue paddingVertical; +@property(nonatomic, readwrite, assign) YGValue padding; -@property (nonatomic, readwrite, assign) CGFloat borderLeftWidth; -@property (nonatomic, readwrite, assign) CGFloat borderTopWidth; -@property (nonatomic, readwrite, assign) CGFloat borderRightWidth; -@property (nonatomic, readwrite, assign) CGFloat borderBottomWidth; -@property (nonatomic, readwrite, assign) CGFloat borderStartWidth; -@property (nonatomic, readwrite, assign) CGFloat borderEndWidth; -@property (nonatomic, readwrite, assign) CGFloat borderWidth; +@property(nonatomic, readwrite, assign) CGFloat borderLeftWidth; +@property(nonatomic, readwrite, assign) CGFloat borderTopWidth; +@property(nonatomic, readwrite, assign) CGFloat borderRightWidth; +@property(nonatomic, readwrite, assign) CGFloat borderBottomWidth; +@property(nonatomic, readwrite, assign) CGFloat borderStartWidth; +@property(nonatomic, readwrite, assign) CGFloat borderEndWidth; +@property(nonatomic, readwrite, assign) CGFloat borderWidth; -@property (nonatomic, readwrite, assign) YGValue width; -@property (nonatomic, readwrite, assign) YGValue height; -@property (nonatomic, readwrite, assign) YGValue minWidth; -@property (nonatomic, readwrite, assign) YGValue minHeight; -@property (nonatomic, readwrite, assign) YGValue maxWidth; -@property (nonatomic, readwrite, assign) YGValue maxHeight; +@property(nonatomic, readwrite, assign) YGValue width; +@property(nonatomic, readwrite, assign) YGValue height; +@property(nonatomic, readwrite, assign) YGValue minWidth; +@property(nonatomic, readwrite, assign) YGValue minHeight; +@property(nonatomic, readwrite, assign) YGValue maxWidth; +@property(nonatomic, readwrite, assign) YGValue maxHeight; // Yoga specific properties, not compatible with flexbox specification -@property (nonatomic, readwrite, assign) CGFloat aspectRatio; +@property(nonatomic, readwrite, assign) CGFloat aspectRatio; /** Get the resolved direction of this node. This won't be YGDirectionInherit */ -@property (nonatomic, readonly, assign) YGDirection resolvedDirection; +@property(nonatomic, readonly, assign) YGDirection resolvedDirection; /** - Perform a layout calculation and update the frames of the views in the hierarchy with the results. - If the origin is not preserved, the root view's layout results will applied from {0,0}. + Perform a layout calculation and update the frames of the views in the + hierarchy with the results. If the origin is not preserved, the root view's + layout results will applied from {0,0}. */ - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin NS_SWIFT_NAME(applyLayout(preservingOrigin:)); /** - Perform a layout calculation and update the frames of the views in the hierarchy with the results. - If the origin is not preserved, the root view's layout results will applied from {0,0}. + Perform a layout calculation and update the frames of the views in the + hierarchy with the results. If the origin is not preserved, the root view's + layout results will applied from {0,0}. */ - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility NS_SWIFT_NAME(applyLayout(preservingOrigin:dimensionFlexibility:)); /** - Returns the size of the view if no constraints were given. This could equivalent to calling [self - sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; + Returns the size of the view if no constraints were given. This could + equivalent to calling [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; */ -@property (nonatomic, readonly, assign) CGSize intrinsicSize; +@property(nonatomic, readonly, assign) CGSize intrinsicSize; /** - Returns the size of the view based on provided constraints. Pass NaN for an unconstrained dimension. + Returns the size of the view based on provided constraints. Pass NaN for an + unconstrained dimension. */ - (CGSize)calculateLayoutWithSize:(CGSize)size NS_SWIFT_NAME(calculateLayout(with:)); @@ -148,19 +152,19 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) { /** Returns the number of children that are using Flexbox. */ -@property (nonatomic, readonly, assign) NSUInteger numberOfChildren; +@property(nonatomic, readonly, assign) NSUInteger numberOfChildren; /** - Return a BOOL indiciating whether or not we this node contains any subviews that are included in - Yoga's layout. + Return a BOOL indiciating whether or not we this node contains any subviews + that are included in Yoga's layout. */ -@property (nonatomic, readonly, assign) BOOL isLeaf; +@property(nonatomic, readonly, assign) BOOL isLeaf; /** Return's a BOOL indicating if a view is dirty. When a node is dirty it usually indicates that it will be remeasured on the next layout pass. */ -@property (nonatomic, readonly, assign) BOOL isDirty; +@property(nonatomic, readonly, assign) BOOL isDirty; /** Mark that a view's layout needs to be recalculated. Only works for leaf views. diff --git a/YogaKit/Source/YGLayout.m b/YogaKit/Source/YGLayout.m index 692020ca..4a95a5ca 100644 --- a/YogaKit/Source/YGLayout.m +++ b/YogaKit/Source/YGLayout.m @@ -5,153 +5,184 @@ * LICENSE file in the root directory of this source tree. */ -#import "YGLayout+Private.h" #import "UIView+Yoga.h" +#import "YGLayout+Private.h" -#define YG_PROPERTY(type, lowercased_name, capitalized_name) \ -- (type)lowercased_name \ -{ \ - return YGNodeStyleGet##capitalized_name(self.node); \ -} \ - \ -- (void)set##capitalized_name:(type)lowercased_name \ -{ \ - YGNodeStyleSet##capitalized_name(self.node, lowercased_name); \ +#define YG_PROPERTY(type, lowercased_name, capitalized_name) \ + -(type)lowercased_name { \ + return YGNodeStyleGet##capitalized_name(self.node); \ + } \ + \ + -(void)set##capitalized_name : (type)lowercased_name { \ + YGNodeStyleSet##capitalized_name(self.node, lowercased_name); \ + } + +#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \ + -(YGValue)lowercased_name { \ + return YGNodeStyleGet##capitalized_name(self.node); \ + } \ + \ + -(void)set##capitalized_name : (YGValue)lowercased_name { \ + switch (lowercased_name.unit) { \ + case YGUnitUndefined: \ + YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \ + break; \ + case YGUnitPoint: \ + YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \ + break; \ + case YGUnitPercent: \ + YGNodeStyleSet##capitalized_name##Percent( \ + self.node, lowercased_name.value); \ + break; \ + default: \ + NSAssert(NO, @"Not implemented"); \ + } \ + } + +#define YG_AUTO_VALUE_PROPERTY(lowercased_name, capitalized_name) \ + -(YGValue)lowercased_name { \ + return YGNodeStyleGet##capitalized_name(self.node); \ + } \ + \ + -(void)set##capitalized_name : (YGValue)lowercased_name { \ + switch (lowercased_name.unit) { \ + case YGUnitPoint: \ + YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \ + break; \ + case YGUnitPercent: \ + YGNodeStyleSet##capitalized_name##Percent( \ + self.node, lowercased_name.value); \ + break; \ + case YGUnitAuto: \ + YGNodeStyleSet##capitalized_name##Auto(self.node); \ + break; \ + default: \ + NSAssert(NO, @"Not implemented"); \ + } \ + } + +#define YG_EDGE_PROPERTY_GETTER( \ + type, lowercased_name, capitalized_name, property, edge) \ + -(type)lowercased_name { \ + return YGNodeStyleGet##property(self.node, edge); \ + } + +#define YG_EDGE_PROPERTY_SETTER( \ + lowercased_name, capitalized_name, property, edge) \ + -(void)set##capitalized_name : (CGFloat)lowercased_name { \ + YGNodeStyleSet##property(self.node, edge, lowercased_name); \ + } + +#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \ + YG_EDGE_PROPERTY_GETTER( \ + CGFloat, lowercased_name, capitalized_name, property, edge) \ + YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) + +#define YG_VALUE_EDGE_PROPERTY_SETTER( \ + objc_lowercased_name, objc_capitalized_name, c_name, edge) \ + -(void)set##objc_capitalized_name : (YGValue)objc_lowercased_name { \ + switch (objc_lowercased_name.unit) { \ + case YGUnitUndefined: \ + YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \ + break; \ + case YGUnitPoint: \ + YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \ + break; \ + case YGUnitPercent: \ + YGNodeStyleSet##c_name##Percent( \ + self.node, edge, objc_lowercased_name.value); \ + break; \ + default: \ + NSAssert(NO, @"Not implemented"); \ + } \ + } + +#define YG_VALUE_EDGE_PROPERTY( \ + lowercased_name, capitalized_name, property, edge) \ + YG_EDGE_PROPERTY_GETTER( \ + YGValue, lowercased_name, capitalized_name, property, edge) \ + YG_VALUE_EDGE_PROPERTY_SETTER( \ + lowercased_name, capitalized_name, property, edge) + +#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name##Left, \ + capitalized_name##Left, \ + capitalized_name, \ + YGEdgeLeft) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name##Top, \ + capitalized_name##Top, \ + capitalized_name, \ + YGEdgeTop) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name##Right, \ + capitalized_name##Right, \ + capitalized_name, \ + YGEdgeRight) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name##Bottom, \ + capitalized_name##Bottom, \ + capitalized_name, \ + YGEdgeBottom) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name##Start, \ + capitalized_name##Start, \ + capitalized_name, \ + YGEdgeStart) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name##End, \ + capitalized_name##End, \ + capitalized_name, \ + YGEdgeEnd) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name##Horizontal, \ + capitalized_name##Horizontal, \ + capitalized_name, \ + YGEdgeHorizontal) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name##Vertical, \ + capitalized_name##Vertical, \ + capitalized_name, \ + YGEdgeVertical) \ + YG_VALUE_EDGE_PROPERTY( \ + lowercased_name, capitalized_name, capitalized_name, YGEdgeAll) + +YGValue YGPointValue(CGFloat value) { + return (YGValue){.value = value, .unit = YGUnitPoint}; } -#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \ -- (YGValue)lowercased_name \ -{ \ - return YGNodeStyleGet##capitalized_name(self.node); \ -} \ - \ -- (void)set##capitalized_name:(YGValue)lowercased_name \ -{ \ - switch (lowercased_name.unit) { \ - case YGUnitUndefined: \ - YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \ - break; \ - case YGUnitPoint: \ - YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \ - break; \ - case YGUnitPercent: \ - YGNodeStyleSet##capitalized_name##Percent(self.node, lowercased_name.value); \ - break; \ - default: \ - NSAssert(NO, @"Not implemented"); \ - } \ -} - -#define YG_AUTO_VALUE_PROPERTY(lowercased_name, capitalized_name) \ -- (YGValue)lowercased_name \ -{ \ - return YGNodeStyleGet##capitalized_name(self.node); \ -} \ - \ -- (void)set##capitalized_name:(YGValue)lowercased_name \ -{ \ - switch (lowercased_name.unit) { \ - case YGUnitPoint: \ - YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \ - break; \ - case YGUnitPercent: \ - YGNodeStyleSet##capitalized_name##Percent(self.node, lowercased_name.value); \ - break; \ - case YGUnitAuto: \ - YGNodeStyleSet##capitalized_name##Auto(self.node); \ - break; \ - default: \ - NSAssert(NO, @"Not implemented"); \ - } \ -} - -#define YG_EDGE_PROPERTY_GETTER(type, lowercased_name, capitalized_name, property, edge) \ -- (type)lowercased_name \ -{ \ - return YGNodeStyleGet##property(self.node, edge); \ -} - -#define YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) \ -- (void)set##capitalized_name:(CGFloat)lowercased_name \ -{ \ - YGNodeStyleSet##property(self.node, edge, lowercased_name); \ -} - -#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \ -YG_EDGE_PROPERTY_GETTER(CGFloat, lowercased_name, capitalized_name, property, edge) \ -YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) - -#define YG_VALUE_EDGE_PROPERTY_SETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \ -- (void)set##objc_capitalized_name:(YGValue)objc_lowercased_name \ -{ \ - switch (objc_lowercased_name.unit) { \ - case YGUnitUndefined: \ - YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \ - break; \ - case YGUnitPoint: \ - YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \ - break; \ - case YGUnitPercent: \ - YGNodeStyleSet##c_name##Percent(self.node, edge, objc_lowercased_name.value); \ - break; \ - default: \ - NSAssert(NO, @"Not implemented"); \ - } \ -} - -#define YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \ -YG_EDGE_PROPERTY_GETTER(YGValue, lowercased_name, capitalized_name, property, edge) \ -YG_VALUE_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) - -#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name##Left, capitalized_name##Left, capitalized_name, YGEdgeLeft) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name##Top, capitalized_name##Top, capitalized_name, YGEdgeTop) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name##Right, capitalized_name##Right, capitalized_name, YGEdgeRight) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name##Bottom, capitalized_name##Bottom, capitalized_name, YGEdgeBottom) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name##Start, capitalized_name##Start, capitalized_name, YGEdgeStart) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name##End, capitalized_name##End, capitalized_name, YGEdgeEnd) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name##Horizontal, capitalized_name##Horizontal, capitalized_name, YGEdgeHorizontal) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name##Vertical, capitalized_name##Vertical, capitalized_name, YGEdgeVertical) \ -YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_name, YGEdgeAll) - -YGValue YGPointValue(CGFloat value) -{ - return (YGValue) { .value = value, .unit = YGUnitPoint }; -} - -YGValue YGPercentValue(CGFloat value) -{ - return (YGValue) { .value = value, .unit = YGUnitPercent }; +YGValue YGPercentValue(CGFloat value) { + return (YGValue){.value = value, .unit = YGUnitPercent}; } static YGConfigRef globalConfig; @interface YGLayout () -@property (nonatomic, weak, readonly) UIView *view; +@property(nonatomic, weak, readonly) UIView* view; @property(nonatomic, assign, readonly) BOOL isUIView; @end @implementation YGLayout -@synthesize isEnabled=_isEnabled; -@synthesize isIncludedInLayout=_isIncludedInLayout; -@synthesize node=_node; +@synthesize isEnabled = _isEnabled; +@synthesize isIncludedInLayout = _isIncludedInLayout; +@synthesize node = _node; -+ (void)initialize -{ ++ (void)initialize { globalConfig = YGConfigNew(); - YGConfigSetExperimentalFeatureEnabled(globalConfig, YGExperimentalFeatureWebFlexBasis, true); + YGConfigSetExperimentalFeatureEnabled( + globalConfig, YGExperimentalFeatureWebFlexBasis, true); YGConfigSetPointScaleFactor(globalConfig, [UIScreen mainScreen].scale); } -- (instancetype)initWithView:(UIView*)view -{ +- (instancetype)initWithView:(UIView*)view { if (self = [super init]) { _view = view; _node = YGNodeNewWithConfig(globalConfig); - YGNodeSetContext(_node, (__bridge void *) view); + YGNodeSetContext(_node, (__bridge void*)view); _isEnabled = NO; _isIncludedInLayout = YES; _isUIView = [view isMemberOfClass:[UIView class]]; @@ -160,18 +191,15 @@ static YGConfigRef globalConfig; return self; } -- (void)dealloc -{ +- (void)dealloc { YGNodeFree(self.node); } -- (BOOL)isDirty -{ +- (BOOL)isDirty { return YGNodeIsDirty(self.node); } -- (void)markDirty -{ +- (void)markDirty { if (self.isDirty || !self.isLeaf) { return; } @@ -187,17 +215,17 @@ static YGConfigRef globalConfig; YGNodeMarkDirty(node); } -- (NSUInteger)numberOfChildren -{ +- (NSUInteger)numberOfChildren { return YGNodeGetChildCount(self.node); } -- (BOOL)isLeaf -{ - NSAssert([NSThread isMainThread], @"This method must be called on the main thread."); +- (BOOL)isLeaf { + NSAssert( + [NSThread isMainThread], + @"This method must be called on the main thread."); if (self.isEnabled) { - for (UIView *subview in self.view.subviews) { - YGLayout *const yoga = subview.yoga; + for (UIView* subview in self.view.subviews) { + YGLayout* const yoga = subview.yoga; if (yoga.isEnabled && yoga.isIncludedInLayout) { return NO; } @@ -209,13 +237,11 @@ static YGConfigRef globalConfig; #pragma mark - Style -- (YGPositionType)position -{ +- (YGPositionType)position { return YGNodeStyleGetPositionType(self.node); } -- (void)setPosition:(YGPositionType)position -{ +- (void)setPosition:(YGPositionType)position { YGNodeStyleSetPositionType(self.node, position); } @@ -261,25 +287,23 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio) #pragma mark - Layout and Sizing -- (YGDirection)resolvedDirection -{ +- (YGDirection)resolvedDirection { return YGNodeLayoutGetDirection(self.node); } -- (void)applyLayout -{ +- (void)applyLayout { [self calculateLayoutWithSize:self.view.bounds.size]; YGApplyLayoutToViewHierarchy(self.view, NO); } -- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin -{ +- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin { [self calculateLayoutWithSize:self.view.bounds.size]; YGApplyLayoutToViewHierarchy(self.view, preserveOrigin); } -- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility -{ +- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin + dimensionFlexibility: + (YGDimensionFlexibility)dimensionFlexibility { CGSize size = self.view.bounds.size; if (dimensionFlexibility & YGDimensionFlexibilityFlexibleWidth) { size.width = YGUndefined; @@ -291,18 +315,15 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio) YGApplyLayoutToViewHierarchy(self.view, preserveOrigin); } - -- (CGSize)intrinsicSize -{ +- (CGSize)intrinsicSize { const CGSize constrainedSize = { - .width = YGUndefined, - .height = YGUndefined, + .width = YGUndefined, + .height = YGUndefined, }; return [self calculateLayoutWithSize:constrainedSize]; } -- (CGSize)calculateLayoutWithSize:(CGSize)size -{ +- (CGSize)calculateLayoutWithSize:(CGSize)size { NSAssert([NSThread isMainThread], @"Yoga calculation must be done on main."); NSAssert(self.isEnabled, @"Yoga is not enabled for this view."); @@ -310,30 +331,28 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio) const YGNodeRef node = self.node; YGNodeCalculateLayout( - node, - size.width, - size.height, - YGNodeStyleGetDirection(node)); + node, size.width, size.height, YGNodeStyleGetDirection(node)); - return (CGSize) { - .width = YGNodeLayoutGetWidth(node), - .height = YGNodeLayoutGetHeight(node), + return (CGSize){ + .width = YGNodeLayoutGetWidth(node), + .height = YGNodeLayoutGetHeight(node), }; } #pragma mark - Private static YGSize YGMeasureView( - YGNodeRef node, - float width, - YGMeasureMode widthMode, - float height, - YGMeasureMode heightMode) -{ - const CGFloat constrainedWidth = (widthMode == YGMeasureModeUndefined) ? CGFLOAT_MAX : width; - const CGFloat constrainedHeight = (heightMode == YGMeasureModeUndefined) ? CGFLOAT_MAX: height; + YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + const CGFloat constrainedWidth = + (widthMode == YGMeasureModeUndefined) ? CGFLOAT_MAX : width; + const CGFloat constrainedHeight = + (heightMode == YGMeasureModeUndefined) ? CGFLOAT_MAX : height; - UIView *view = (__bridge UIView*) YGNodeGetContext(node); + UIView* view = (__bridge UIView*)YGNodeGetContext(node); CGSize sizeThatFits = CGSizeZero; // The default implementation of sizeThatFits: returns the existing size of @@ -349,17 +368,18 @@ static YGSize YGMeasureView( }]; } - return (YGSize) { - .width = YGSanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode), - .height = YGSanitizeMeasurement(constrainedHeight, sizeThatFits.height, heightMode), + return (YGSize){ + .width = YGSanitizeMeasurement( + constrainedWidth, sizeThatFits.width, widthMode), + .height = YGSanitizeMeasurement( + constrainedHeight, sizeThatFits.height, heightMode), }; } static CGFloat YGSanitizeMeasurement( - CGFloat constrainedSize, - CGFloat measuredSize, - YGMeasureMode measureMode) -{ + CGFloat constrainedSize, + CGFloat measuredSize, + YGMeasureMode measureMode) { CGFloat result; if (measureMode == YGMeasureModeExactly) { result = constrainedSize; @@ -372,13 +392,14 @@ static CGFloat YGSanitizeMeasurement( return result; } -static BOOL YGNodeHasExactSameChildren(const YGNodeRef node, NSArray *subviews) -{ +static BOOL YGNodeHasExactSameChildren( + const YGNodeRef node, + NSArray* subviews) { if (YGNodeGetChildCount(node) != subviews.count) { return NO; } - for (int i=0; i * return YES; } -static void YGAttachNodesFromViewHierachy(UIView *const view) -{ - YGLayout *const yoga = view.yoga; +static void YGAttachNodesFromViewHierachy(UIView* const view) { + YGLayout* const yoga = view.yoga; const YGNodeRef node = yoga.node; // Only leaf nodes should have a measure function @@ -399,8 +419,9 @@ static void YGAttachNodesFromViewHierachy(UIView *const view) } else { YGNodeSetMeasureFunc(node, NULL); - NSMutableArray *subviewsToInclude = [[NSMutableArray alloc] initWithCapacity:view.subviews.count]; - for (UIView *subview in view.subviews) { + NSMutableArray* subviewsToInclude = + [[NSMutableArray alloc] initWithCapacity:view.subviews.count]; + for (UIView* subview in view.subviews) { if (subview.yoga.isEnabled && subview.yoga.isIncludedInLayout) { [subviewsToInclude addObject:subview]; } @@ -408,19 +429,18 @@ static void YGAttachNodesFromViewHierachy(UIView *const view) if (!YGNodeHasExactSameChildren(node, subviewsToInclude)) { YGRemoveAllChildren(node); - for (int i=0; i diff --git a/java/jni/ScopedGlobalRef.h b/java/jni/ScopedGlobalRef.h index b1c18e68..fa98214a 100644 --- a/java/jni/ScopedGlobalRef.h +++ b/java/jni/ScopedGlobalRef.h @@ -84,9 +84,7 @@ public: return *this; } - ~ScopedGlobalRef() { - reset(); - } + ~ScopedGlobalRef() { reset(); } /** * Deletes the currently held reference and reassigns a new one to the @@ -120,9 +118,7 @@ public: /** * Returns true if the underlying JNI reference is not NULL. */ - operator bool() const { - return mGlobalRef != NULL; - } + operator bool() const { return mGlobalRef != NULL; } ScopedGlobalRef(const ScopedGlobalRef& ref) = delete; ScopedGlobalRef& operator=(const ScopedGlobalRef& other) = delete; diff --git a/java/jni/ScopedLocalRef.h b/java/jni/ScopedLocalRef.h index 0c5e9440..2368ced2 100644 --- a/java/jni/ScopedLocalRef.h +++ b/java/jni/ScopedLocalRef.h @@ -83,9 +83,7 @@ public: return *this; } - ~ScopedLocalRef() { - reset(); - } + ~ScopedLocalRef() { reset(); } /** * Deletes the currently held reference and reassigns a new one to the @@ -119,9 +117,7 @@ public: /** * Returns true if the underlying JNI reference is not NULL. */ - operator bool() const { - return mLocalRef != NULL; - } + operator bool() const { return mLocalRef != NULL; } ScopedLocalRef(const ScopedLocalRef& ref) = delete; ScopedLocalRef& operator=(const ScopedLocalRef& other) = delete; diff --git a/java/jni/common.cpp b/java/jni/common.cpp index 143c695f..37b56770 100644 --- a/java/jni/common.cpp +++ b/java/jni/common.cpp @@ -77,8 +77,11 @@ DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(void, Void) { assertNoPendingJniException(env); } -ScopedLocalRef -callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...) { +ScopedLocalRef callStaticObjectMethod( + JNIEnv* env, + jclass clazz, + jmethodID methodId, + ...) { va_list args; va_start(args, methodId); jobject result = env->CallStaticObjectMethodV(clazz, methodId, args); diff --git a/java/jni/common.h b/java/jni/common.h index 19eca6a4..fda1e06d 100644 --- a/java/jni/common.h +++ b/java/jni/common.h @@ -61,8 +61,11 @@ DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(void, Void); DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(jlong, Long); DEFINE_CALL_METHOD_FOR_PRIMITIVE_INTERFACE(jfloat, Float); -ScopedLocalRef -callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...); +ScopedLocalRef callStaticObjectMethod( + JNIEnv* env, + jclass clazz, + jmethodID methodId, + ...); /** * Given a local or a global reference, this method creates a new global diff --git a/javascript/sources/Size.hh b/javascript/sources/Size.hh index d7ea6da9..9f550a96 100644 --- a/javascript/sources/Size.hh +++ b/javascript/sources/Size.hh @@ -18,7 +18,5 @@ struct Size { Size(double width, double height) : width(width), height(height) {} - void toJS(nbind::cbOutput expose) const { - expose(width, height); - } + void toJS(nbind::cbOutput expose) const { expose(width, height); } }; diff --git a/javascript/sources/Value.hh b/javascript/sources/Value.hh index e7a9cf66..2581ae4a 100644 --- a/javascript/sources/Value.hh +++ b/javascript/sources/Value.hh @@ -21,7 +21,5 @@ struct Value { Value(int unit, double value) : unit(unit), value(value) {} - void toJS(nbind::cbOutput expose) const { - expose(unit, value); - } + void toJS(nbind::cbOutput expose) const { expose(unit, value); } }; From 6c61cd5f05abe51d33c67db13df74206a908e1d6 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Wed, 19 Feb 2020 11:10:06 -0800 Subject: [PATCH 20/87] Fix layout tab scrolling in playground Summary: Add a scroll bar to layout tab in playground to fix the UI issue where margin, border were not accessible. Reviewed By: danielbuechele Differential Revision: D19906128 fbshipit-source-id: 2c2d7695f731b2d312b78eab31c66d737915eaae --- website/src/components/Playground/src/Editor.css | 3 ++- website/src/components/Playground/src/Editor.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/website/src/components/Playground/src/Editor.css b/website/src/components/Playground/src/Editor.css index f53451f7..78974f63 100644 --- a/website/src/components/Playground/src/Editor.css +++ b/website/src/components/Playground/src/Editor.css @@ -51,7 +51,8 @@ } .Editor .ant-tabs-tabpane { - overflow-y: scroll; + overflow-y: auto; + height: 45vh; padding: 15px; } diff --git a/website/src/components/Playground/src/Editor.js b/website/src/components/Playground/src/Editor.js index f7076865..4b6b6593 100644 --- a/website/src/components/Playground/src/Editor.js +++ b/website/src/components/Playground/src/Editor.js @@ -196,7 +196,7 @@ export default class Editor extends Component { onChange={this.props.onChangeLayout} /> - +

Width × Height From 2d52b5a8733bccba663b15817685b13d8b5eb9da Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Tue, 25 Feb 2020 07:27:56 -0800 Subject: [PATCH 21/87] fix layout tab height issue in playground on home page Summary: Fixed layout tab height issue properly Reviewed By: danielbuechele Differential Revision: D20003594 fbshipit-source-id: 6d9ce89a5d82a83937e5cb0f989bb028e07d576f --- website/src/components/Playground/src/Editor.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/src/components/Playground/src/Editor.css b/website/src/components/Playground/src/Editor.css index 78974f63..57954947 100644 --- a/website/src/components/Playground/src/Editor.css +++ b/website/src/components/Playground/src/Editor.css @@ -52,7 +52,9 @@ .Editor .ant-tabs-tabpane { overflow-y: auto; - height: 45vh; + min-height: 320px; + height: 100%; + max-height: 25vh; padding: 15px; } From adb87e347f7488405be77d5fb964290c55a11c7f Mon Sep 17 00:00:00 2001 From: Jesse Katsumata Date: Mon, 9 Mar 2020 15:34:16 -0700 Subject: [PATCH 22/87] chore: fix typo in comments (#28269) Summary: Fixed some typos in the comment. ## Changelog [Internal] [Fixed] - Fixed typo in the comments Pull Request resolved: https://github.com/facebook/react-native/pull/28269 Test Plan: Changes are only made in the comments, so test is not necessary. Reviewed By: cpojer Differential Revision: D20342637 Pulled By: shergin fbshipit-source-id: f6e7dd538ee54c43e1570c35e1f8c4502054e328 --- yoga/YGNode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 95962e68..9aef1ec6 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -73,7 +73,7 @@ private: } // DANGER DANGER DANGER! - // If the the node assigned to has children, we'd either have to deallocate + // If the node assigned to has children, we'd either have to deallocate // them (potentially incorrect) or ignore them (danger of leaks). Only ever // use this after checking that there are no children. // DO NOT CHANGE THE VISIBILITY OF THIS METHOD! From 63a463d01149d363cd9c57fa8d07074203cf5a0a Mon Sep 17 00:00:00 2001 From: Nate Stedman Date: Tue, 10 Mar 2020 09:35:55 -0700 Subject: [PATCH 23/87] Mark YogaKit as modular Differential Revision: D20364340 fbshipit-source-id: ce4bc1f474177ffc9c77eb2f10bdb7cb549dd6d8 --- YogaKit/BUCK | 2 ++ 1 file changed, 2 insertions(+) diff --git a/YogaKit/BUCK b/YogaKit/BUCK index c3d534e8..0bff3caa 100644 --- a/YogaKit/BUCK +++ b/YogaKit/BUCK @@ -42,6 +42,8 @@ yoga_apple_library( ], header_path_prefix = "", link_whole = True, + modular = True, + module_name = "YogaKit", visibility = ["PUBLIC"], deps = [ yoga_dep(":yoga"), From b280a19b0a61d6119ac48b441bcfd9cedd416113 Mon Sep 17 00:00:00 2001 From: Adam Ernst Date: Tue, 10 Mar 2020 10:55:08 -0700 Subject: [PATCH 24/87] Run 'arc lint-deps' Reviewed By: d16r Differential Revision: D20362505 fbshipit-source-id: f3b7e62f7665d20a32788042772b731d6ed53f36 --- YogaKit/BUCK | 1 + 1 file changed, 1 insertion(+) diff --git a/YogaKit/BUCK b/YogaKit/BUCK index 0bff3caa..acefcdb3 100644 --- a/YogaKit/BUCK +++ b/YogaKit/BUCK @@ -37,6 +37,7 @@ yoga_apple_library( ), compiler_flags = COMPILER_FLAGS, frameworks = [ + "$SDKROOT/System/Library/Frameworks/CoreGraphics.framework", "$SDKROOT/System/Library/Frameworks/Foundation.framework", "$SDKROOT/System/Library/Frameworks/UIKit.framework", ], From 4f1231f411b88c6e280a7ad2aa1354dc111b337d Mon Sep 17 00:00:00 2001 From: Lior Israeli Date: Tue, 24 Mar 2020 05:18:30 -0700 Subject: [PATCH 25/87] Fix typo in buck targets Summary: Proguard is spelled wrong Reviewed By: SidharthGuglani Differential Revision: D20619173 fbshipit-source-id: 463788454ad7e72337121ed63ab79129db45113e --- android/BUCK | 4 ++-- java/BUCK | 6 +++--- lib/fb/src/main/java/com/facebook/jni/BUCK | 4 ++-- tools/build_defs/oss/yoga_defs.bzl | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/BUCK b/android/BUCK index 649b96a3..6acb3325 100644 --- a/android/BUCK +++ b/android/BUCK @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID_JAVA_TARGET", "ANDROID_RES_TARGET", "JAVA_TARGET", "PROGRUARD_ANNOTATIONS_TARGET", "yoga_android_aar", "yoga_android_resource") +load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID_JAVA_TARGET", "ANDROID_RES_TARGET", "JAVA_TARGET", "PROGUARD_ANNOTATIONS_TARGET", "yoga_android_aar", "yoga_android_resource") yoga_android_aar( name = "android", @@ -15,7 +15,7 @@ yoga_android_aar( ANDROID_JAVA_TARGET, ANDROID_RES_TARGET, JAVA_TARGET, - PROGRUARD_ANNOTATIONS_TARGET, + PROGUARD_ANNOTATIONS_TARGET, ], ) diff --git a/java/BUCK b/java/BUCK index 72be4261..221e8265 100644 --- a/java/BUCK +++ b/java/BUCK @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID", "CXX_LIBRARY_WHITELIST", "JNI_TARGET", "JSR_305_TARGET", "JUNIT_TARGET", "PROGRUARD_ANNOTATIONS_TARGET", "SOLOADER_TARGET", "YOGA_ROOTS", "yoga_cxx_lib", "yoga_cxx_library", "yoga_dep", "yoga_java_binary", "yoga_java_library", "yoga_java_test", "yoga_prebuilt_cxx_library") +load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID", "CXX_LIBRARY_WHITELIST", "JNI_TARGET", "JSR_305_TARGET", "JUNIT_TARGET", "PROGUARD_ANNOTATIONS_TARGET", "SOLOADER_TARGET", "YOGA_ROOTS", "yoga_cxx_lib", "yoga_cxx_library", "yoga_dep", "yoga_java_binary", "yoga_java_library", "yoga_java_test", "yoga_prebuilt_cxx_library") CXX_LIBRARY_WHITELIST_FOR_TESTS = CXX_LIBRARY_WHITELIST + [ yoga_cxx_lib("testutil:jni"), @@ -71,7 +71,7 @@ yoga_java_library( visibility = ["PUBLIC"], deps = [ JSR_305_TARGET, - PROGRUARD_ANNOTATIONS_TARGET, + PROGUARD_ANNOTATIONS_TARGET, ], ) @@ -85,7 +85,7 @@ yoga_java_library( ":java-interface", ":jni", JSR_305_TARGET, - PROGRUARD_ANNOTATIONS_TARGET, + PROGUARD_ANNOTATIONS_TARGET, SOLOADER_TARGET, ], ) diff --git a/lib/fb/src/main/java/com/facebook/jni/BUCK b/lib/fb/src/main/java/com/facebook/jni/BUCK index e048811d..38526c26 100644 --- a/lib/fb/src/main/java/com/facebook/jni/BUCK +++ b/lib/fb/src/main/java/com/facebook/jni/BUCK @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -load("//tools/build_defs/oss:yoga_defs.bzl", "JSR_305_TARGET", "PROGRUARD_ANNOTATIONS_TARGET", "SOLOADER_TARGET", "yoga_java_library") +load("//tools/build_defs/oss:yoga_defs.bzl", "JSR_305_TARGET", "PROGUARD_ANNOTATIONS_TARGET", "SOLOADER_TARGET", "yoga_java_library") yoga_java_library( name = "jni", @@ -13,7 +13,7 @@ yoga_java_library( "PUBLIC", ], deps = [ - PROGRUARD_ANNOTATIONS_TARGET, + PROGUARD_ANNOTATIONS_TARGET, SOLOADER_TARGET, JSR_305_TARGET, ], diff --git a/tools/build_defs/oss/yoga_defs.bzl b/tools/build_defs/oss/yoga_defs.bzl index 4c50e984..253449b3 100644 --- a/tools/build_defs/oss/yoga_defs.bzl +++ b/tools/build_defs/oss/yoga_defs.bzl @@ -14,7 +14,7 @@ JSR_305_TARGET = "//lib/jsr-305:jsr-305" JUNIT_TARGET = "//lib/junit:junit" -PROGRUARD_ANNOTATIONS_TARGET = "//java/proguard-annotations/src/main/java/com/facebook/proguard/annotations:annotations" +PROGUARD_ANNOTATIONS_TARGET = "//java/proguard-annotations/src/main/java/com/facebook/proguard/annotations:annotations" SOLOADER_TARGET = "//lib/soloader:soloader" From 5bf93e81ba4547902d7554d055f0b53eb7bafdfa Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Tue, 24 Mar 2020 20:18:20 -0700 Subject: [PATCH 26/87] Upgrade Prettier from 1.17 to 2.0.2. Summary: This gets us on the latest Prettier 2.x: https://prettier.io/blog/2020/03/21/2.0.0.html Notably, this adds support for TypeScript 3.8, which introduces new syntax, such as `import type`. Reviewed By: zertosh Differential Revision: D20636268 fbshipit-source-id: fca5833d003804333a05ba16325bbbe0e06d6c8a --- website/package.json | 2 +- .../Playground/src/CodeJavaScript.js | 8 ++++--- .../components/Playground/src/CodeLitho.js | 4 ++-- .../components/Playground/src/URLShortener.js | 4 +--- .../Playground/src/YogaEnumSelect.js | 5 +---- website/src/pages/docs/index.js | 21 +++++++++---------- website/yarn.lock | 8 +++---- 7 files changed, 24 insertions(+), 28 deletions(-) diff --git a/website/package.json b/website/package.json index 442b13f6..218c1e73 100644 --- a/website/package.json +++ b/website/package.json @@ -32,6 +32,6 @@ "develop": "gatsby develop" }, "devDependencies": { - "prettier": "1.17.0" + "prettier": "2.0.2" } } diff --git a/website/src/components/Playground/src/CodeJavaScript.js b/website/src/components/Playground/src/CodeJavaScript.js index a16a586c..efa48ec0 100644 --- a/website/src/components/Playground/src/CodeJavaScript.js +++ b/website/src/components/Playground/src/CodeJavaScript.js @@ -27,9 +27,11 @@ export const JSEnumLookup = { }; function getEnum(yogaEnum: string, value: string | number): string { - return `yoga.${Object.keys(yoga) - .filter(key => key.toLowerCase().startsWith(yogaEnum.toLowerCase())) - .find(key => yoga[key] === value) || value}`; + return `yoga.${ + Object.keys(yoga) + .filter(key => key.toLowerCase().startsWith(yogaEnum.toLowerCase())) + .find(key => yoga[key] === value) || value + }`; } function setProperty( diff --git a/website/src/components/Playground/src/CodeLitho.js b/website/src/components/Playground/src/CodeLitho.js index 0e9f782b..66e89a3e 100644 --- a/website/src/components/Playground/src/CodeLitho.js +++ b/website/src/components/Playground/src/CodeLitho.js @@ -47,8 +47,8 @@ function dipOrPercent(value) { return value === 'auto' ? 'Auto' : typeof value === 'string' && /%$/.test(value) - ? 'Percent' - : 'Dip'; + ? 'Percent' + : 'Dip'; } function getValue(value) { diff --git a/website/src/components/Playground/src/URLShortener.js b/website/src/components/Playground/src/URLShortener.js index 77130a0f..27049801 100644 --- a/website/src/components/Playground/src/URLShortener.js +++ b/website/src/components/Playground/src/URLShortener.js @@ -52,9 +52,7 @@ export default class URLShortener extends Component<{}, State> { } fetch( - `https://cors-anywhere.herokuapp.com/tinyurl.com/api-create.php?url=${ - window.location.href - }`, + `https://cors-anywhere.herokuapp.com/tinyurl.com/api-create.php?url=${window.location.href}`, ) .then(res => res.text()) .then(shortURL => this.setState({shortURL, loading: false})) diff --git a/website/src/components/Playground/src/YogaEnumSelect.js b/website/src/components/Playground/src/YogaEnumSelect.js index 04ce3968..8c7f297e 100644 --- a/website/src/components/Playground/src/YogaEnumSelect.js +++ b/website/src/components/Playground/src/YogaEnumSelect.js @@ -57,10 +57,7 @@ export default class YogaEnumSelect extends Component { getTitle = (property: string, key: string): string => { const replacer = new RegExp(`^${property}_`); - return key - .replace(replacer, '') - .replace('_', ' ') - .toLowerCase(); + return key.replace(replacer, '').replace('_', ' ').toLowerCase(); }; render() { diff --git a/website/src/pages/docs/index.js b/website/src/pages/docs/index.js index 66e0a363..96dee1ae 100644 --- a/website/src/pages/docs/index.js +++ b/website/src/pages/docs/index.js @@ -49,17 +49,16 @@ export default ({data}) => ( ({node}) => node.fileAbsolutePath.indexOf(`/${category}/`) > -1, ) - .map( - ({node}) => - node.frontmatter.redirect ? ( - - {node.frontmatter.title} - - ) : ( - - {node.frontmatter.title} - - ), + .map(({node}) => + node.frontmatter.redirect ? ( + + {node.frontmatter.title} + + ) : ( + + {node.frontmatter.title} + + ), )} ), diff --git a/website/yarn.lock b/website/yarn.lock index 509efeca..9cb28ac6 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -6978,10 +6978,10 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" - integrity sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw== +prettier@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" + integrity sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg== pretty-bytes@^4.0.2: version "4.0.2" From 0f08aa53dab729324b9706a833e219ee654c64a6 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Tue, 24 Mar 2020 21:35:58 -0700 Subject: [PATCH 27/87] Back out "Upgrade Prettier from 1.17 to 2.0.2." Differential Revision: D20639755 fbshipit-source-id: 5028563f9cf0527a30b4259daac50cdc03934bfd --- website/package.json | 2 +- .../Playground/src/CodeJavaScript.js | 8 +++---- .../components/Playground/src/CodeLitho.js | 4 ++-- .../components/Playground/src/URLShortener.js | 4 +++- .../Playground/src/YogaEnumSelect.js | 5 ++++- website/src/pages/docs/index.js | 21 ++++++++++--------- website/yarn.lock | 8 +++---- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/website/package.json b/website/package.json index 218c1e73..442b13f6 100644 --- a/website/package.json +++ b/website/package.json @@ -32,6 +32,6 @@ "develop": "gatsby develop" }, "devDependencies": { - "prettier": "2.0.2" + "prettier": "1.17.0" } } diff --git a/website/src/components/Playground/src/CodeJavaScript.js b/website/src/components/Playground/src/CodeJavaScript.js index efa48ec0..a16a586c 100644 --- a/website/src/components/Playground/src/CodeJavaScript.js +++ b/website/src/components/Playground/src/CodeJavaScript.js @@ -27,11 +27,9 @@ export const JSEnumLookup = { }; function getEnum(yogaEnum: string, value: string | number): string { - return `yoga.${ - Object.keys(yoga) - .filter(key => key.toLowerCase().startsWith(yogaEnum.toLowerCase())) - .find(key => yoga[key] === value) || value - }`; + return `yoga.${Object.keys(yoga) + .filter(key => key.toLowerCase().startsWith(yogaEnum.toLowerCase())) + .find(key => yoga[key] === value) || value}`; } function setProperty( diff --git a/website/src/components/Playground/src/CodeLitho.js b/website/src/components/Playground/src/CodeLitho.js index 66e89a3e..0e9f782b 100644 --- a/website/src/components/Playground/src/CodeLitho.js +++ b/website/src/components/Playground/src/CodeLitho.js @@ -47,8 +47,8 @@ function dipOrPercent(value) { return value === 'auto' ? 'Auto' : typeof value === 'string' && /%$/.test(value) - ? 'Percent' - : 'Dip'; + ? 'Percent' + : 'Dip'; } function getValue(value) { diff --git a/website/src/components/Playground/src/URLShortener.js b/website/src/components/Playground/src/URLShortener.js index 27049801..77130a0f 100644 --- a/website/src/components/Playground/src/URLShortener.js +++ b/website/src/components/Playground/src/URLShortener.js @@ -52,7 +52,9 @@ export default class URLShortener extends Component<{}, State> { } fetch( - `https://cors-anywhere.herokuapp.com/tinyurl.com/api-create.php?url=${window.location.href}`, + `https://cors-anywhere.herokuapp.com/tinyurl.com/api-create.php?url=${ + window.location.href + }`, ) .then(res => res.text()) .then(shortURL => this.setState({shortURL, loading: false})) diff --git a/website/src/components/Playground/src/YogaEnumSelect.js b/website/src/components/Playground/src/YogaEnumSelect.js index 8c7f297e..04ce3968 100644 --- a/website/src/components/Playground/src/YogaEnumSelect.js +++ b/website/src/components/Playground/src/YogaEnumSelect.js @@ -57,7 +57,10 @@ export default class YogaEnumSelect extends Component { getTitle = (property: string, key: string): string => { const replacer = new RegExp(`^${property}_`); - return key.replace(replacer, '').replace('_', ' ').toLowerCase(); + return key + .replace(replacer, '') + .replace('_', ' ') + .toLowerCase(); }; render() { diff --git a/website/src/pages/docs/index.js b/website/src/pages/docs/index.js index 96dee1ae..66e0a363 100644 --- a/website/src/pages/docs/index.js +++ b/website/src/pages/docs/index.js @@ -49,16 +49,17 @@ export default ({data}) => ( ({node}) => node.fileAbsolutePath.indexOf(`/${category}/`) > -1, ) - .map(({node}) => - node.frontmatter.redirect ? ( - - {node.frontmatter.title} - - ) : ( - - {node.frontmatter.title} - - ), + .map( + ({node}) => + node.frontmatter.redirect ? ( + + {node.frontmatter.title} + + ) : ( + + {node.frontmatter.title} + + ), )} ), diff --git a/website/yarn.lock b/website/yarn.lock index 9cb28ac6..509efeca 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -6978,10 +6978,10 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" - integrity sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg== +prettier@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" + integrity sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw== pretty-bytes@^4.0.2: version "4.0.2" From ecd7790dd8192b4c2944f85e28df2fc589b908c0 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Wed, 1 Apr 2020 14:37:45 -0700 Subject: [PATCH 28/87] Fix Yoga flexshrink with min-width sizing issue Summary: While resolving the flexible items we calculate totalFlexShrinkScaledFactors which uses the flexBasis or initial width of node (Not min-width). At a later stage during distribution of space we are subtracting value from this which also takes care of min-width. For example If node has flexShrink 1 and width 100 and min-width 301 then totalFlexShrinkScaledFactors will become -1*100 = -100 but later we are subtracting -1 * 301 (min-width) = -301 which is ambiguous and causing layout inconsistencies with how web behaves. Fixed this by only using the flexBasis or width for these calculations. Changelog: [Internal][Yoga] Fix layout issue when flexShrink and min-width are used together Reviewed By: pasqualeanatriello Differential Revision: D20219419 fbshipit-source-id: 948fbc06ca541d4ad307c88c8a2df65d157778b1 --- yoga/Yoga.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index e30a36b7..d916a45f 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -2338,7 +2338,8 @@ static void YGDistributeFreeSpaceFirstPass( // first and second passes. deltaFreeSpace += boundMainSize - childFlexBasis; collectedFlexItemsValues.totalFlexShrinkScaledFactors -= - flexShrinkScaledFactor; + (-currentRelativeChild->resolveFlexShrink() * + currentRelativeChild->getLayout().computedFlexBasis.unwrap()); } } } else if ( From 2049c85a6cda69f54ed4657199f888e8be513328 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Wed, 1 Apr 2020 14:37:45 -0700 Subject: [PATCH 29/87] Unit tests for flexshrink min width cases Reviewed By: pasqualeanatriello Differential Revision: D20219428 fbshipit-source-id: 8cbd028627095d9f7b393489ddba1f31c3207b67 --- tests/YGFlexTest.cpp | 118 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/tests/YGFlexTest.cpp b/tests/YGFlexTest.cpp index 21c7578d..ab6dec76 100644 --- a/tests/YGFlexTest.cpp +++ b/tests/YGFlexTest.cpp @@ -605,3 +605,121 @@ TEST(YogaTest, flex_grow_less_than_factor_one) { YGConfigFree(config); } + +TEST(YogaTest, flex_shrink_min_width) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetMinWidth(root_child0, 301); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetMinWidth(root_child1, 25); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child2, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(401, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(99, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_shrink_flex_grow_min_width) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetUseWebDefaults(config, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexGrow(root_child0, 0); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetMinWidth(root_child0, 301); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetMinWidth(root_child1, 25); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child2, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeStyleSetFlexShrink(root_child2, 1); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(401, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(99, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} From 5eba2d42bd6fde1092439cbc3388ae0a3cc561d9 Mon Sep 17 00:00:00 2001 From: Gavin Weng Date: Mon, 6 Apr 2020 11:45:21 -0700 Subject: [PATCH 30/87] Enhance build process (#994) Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/994 After building yoga aar, we found several issues: 1. More dynamic so files. This is bad as lower-end Android devices cannot load that many sos. 2. Size increase. 3. (Minor) The libs are stored in asset folder rather than "libs/". We apply the following optimizations: 1. Remove dependency on memalign16 (this is brought in by a pure header dependency jni-hack); 2. Enable native relinker to remove unused symbols in the so files. 3. Link yogacore statically to reduce size churn. Reviewed By: SidharthGuglani Differential Revision: D20808623 fbshipit-source-id: 6c6bbd4f71b6bf6ad272ec05dd56696ddb14a8e0 --- BUCK | 14 ++++++++++++++ android/BUCK | 1 + java/BUCK | 4 ++-- testutil/BUCK | 14 +++++++++++++- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/BUCK b/BUCK index fa0e5580..eb96206f 100644 --- a/BUCK +++ b/BUCK @@ -40,6 +40,20 @@ yoga_cxx_library( ], ) +yoga_cxx_library( + name = "yoga-static", + srcs = glob(["yoga/**/*.cpp"]), + compiler_flags = LIBRARY_COMPILER_FLAGS, + preferred_linkage = "static", + public_include_directories = ["."], + raw_headers = glob(["yoga/**/*.h"]), + tests = [":YogaTests"], + visibility = ["PUBLIC"], + deps = [ + ":ndklog", + ], +) + yoga_cxx_library( name = "yogaForDebug", srcs = glob(["yoga/**/*.cpp"]), diff --git a/android/BUCK b/android/BUCK index 6acb3325..72548072 100644 --- a/android/BUCK +++ b/android/BUCK @@ -7,6 +7,7 @@ load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID_JAVA_TARGET", "ANDROID_RES yoga_android_aar( name = "android", + enable_relinker = True, manifest_skeleton = "src/main/AndroidManifest.xml", visibility = [ "PUBLIC", diff --git a/java/BUCK b/java/BUCK index 221e8265..d08cb37b 100644 --- a/java/BUCK +++ b/java/BUCK @@ -7,7 +7,7 @@ load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID", "CXX_LIBRARY_WHITELIST", CXX_LIBRARY_WHITELIST_FOR_TESTS = CXX_LIBRARY_WHITELIST + [ yoga_cxx_lib("testutil:jni"), - yoga_cxx_lib("testutil:testutil"), + yoga_cxx_lib("testutil:testutil-jni"), ] YOGA_JAVA_IMPLEMENTATION_FILES = [ @@ -54,7 +54,7 @@ yoga_cxx_library( visibility = ["PUBLIC"], deps = [ JNI_TARGET, - yoga_dep(":yoga"), + yoga_dep(":yoga-static"), ":ndklog", ], ) diff --git a/testutil/BUCK b/testutil/BUCK index 56ee97fe..acbabc11 100644 --- a/testutil/BUCK +++ b/testutil/BUCK @@ -11,6 +11,18 @@ yoga_cxx_library( deps = [yoga_dep(":yoga")], ) +yoga_cxx_library( + name = "testutil-jni", + srcs = ["src/main/cpp/testutil/testutil.cpp"], + header_namespace = "", + exported_headers = subdir_glob([("src/main/cpp/include", "yoga/testutil/testutil.h")]), + compiler_flags = LIBRARY_COMPILER_FLAGS, + platforms = ANDROID, + soname = "libyoga_testutil.$(ext)", + visibility = ["PUBLIC"], + deps = [yoga_dep("java:jni")], +) + yoga_java_library( name = "java", srcs = ["src/main/java/com/facebook/yoga/TestUtil.java"], @@ -32,7 +44,7 @@ yoga_cxx_library( soname = "libyoga_testutil_jni.$(ext)", visibility = ["PUBLIC"], deps = [ - ":testutil", + ":testutil-jni", FBJNI_TARGET, ], ) From be51bc44a48da64c346309995b443c96610b43a1 Mon Sep 17 00:00:00 2001 From: Gavin Weng Date: Mon, 6 Apr 2020 19:51:09 -0700 Subject: [PATCH 31/87] Revert Name Change for FBLite Summary: To unblock Reviewed By: Arieg419 Differential Revision: D20879886 fbshipit-source-id: 428f9147e540b94dec7f72a7f844949722165a07 --- java/BUCK | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/BUCK b/java/BUCK index d08cb37b..034024cd 100644 --- a/java/BUCK +++ b/java/BUCK @@ -54,7 +54,7 @@ yoga_cxx_library( visibility = ["PUBLIC"], deps = [ JNI_TARGET, - yoga_dep(":yoga-static"), + yoga_dep(":yoga"), ":ndklog", ], ) From 8c53c2dcca9a7acf3733c00e5820f5a18f075024 Mon Sep 17 00:00:00 2001 From: George Zahariev Date: Thu, 9 Apr 2020 10:55:48 -0700 Subject: [PATCH 32/87] Upgrade Prettier in Xplat to version 1.19.1 Summary: Upgrades Prettier in Xplat to 1.19.1 Ignores upgrading packages on already on versions greater than 1.19.1 Changelog: [Internal] allow-large-files bypass-lint (Note: this ignores all push blocking failures!) Reviewed By: gkz, cpojer Differential Revision: D20879147 fbshipit-source-id: 0deee7ac941e91e1c3c3a1e7d3d3ed20de1d657d --- website/package.json | 2 +- website/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/package.json b/website/package.json index 442b13f6..53445418 100644 --- a/website/package.json +++ b/website/package.json @@ -32,6 +32,6 @@ "develop": "gatsby develop" }, "devDependencies": { - "prettier": "1.17.0" + "prettier": "1.19.1" } } diff --git a/website/yarn.lock b/website/yarn.lock index 509efeca..fa5a26e2 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -6978,10 +6978,10 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" - integrity sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw== +prettier@1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== pretty-bytes@^4.0.2: version "4.0.2" From f7bc0ad2489c1b09d0cc0d53f668861f5d7875a0 Mon Sep 17 00:00:00 2001 From: George Zahariev Date: Thu, 9 Apr 2020 10:55:48 -0700 Subject: [PATCH 33/87] Upgrade Prettier in Xplat to version 1.19.1: format files Summary: Part two of D20879147 where we update the versions of Prettier used in Xplat. I will stack land the diffs. Here, we format all the files, and use the drop conflicts flag. After this lands, I will go and format the files which had conflicts again. Changelog: [Internal] drop-conflicts bypass-lint allow-large-files Reviewed By: gkz Differential Revision: D20929844 fbshipit-source-id: 2c1df8966a48b5db4f890e2cc494cb1c69422b7d --- .../components/Playground/src/CodeLitho.js | 4 ++-- .../components/Playground/src/URLShortener.js | 4 +--- website/src/pages/docs/index.js | 21 +++++++++---------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/website/src/components/Playground/src/CodeLitho.js b/website/src/components/Playground/src/CodeLitho.js index 0e9f782b..66e89a3e 100644 --- a/website/src/components/Playground/src/CodeLitho.js +++ b/website/src/components/Playground/src/CodeLitho.js @@ -47,8 +47,8 @@ function dipOrPercent(value) { return value === 'auto' ? 'Auto' : typeof value === 'string' && /%$/.test(value) - ? 'Percent' - : 'Dip'; + ? 'Percent' + : 'Dip'; } function getValue(value) { diff --git a/website/src/components/Playground/src/URLShortener.js b/website/src/components/Playground/src/URLShortener.js index 77130a0f..27049801 100644 --- a/website/src/components/Playground/src/URLShortener.js +++ b/website/src/components/Playground/src/URLShortener.js @@ -52,9 +52,7 @@ export default class URLShortener extends Component<{}, State> { } fetch( - `https://cors-anywhere.herokuapp.com/tinyurl.com/api-create.php?url=${ - window.location.href - }`, + `https://cors-anywhere.herokuapp.com/tinyurl.com/api-create.php?url=${window.location.href}`, ) .then(res => res.text()) .then(shortURL => this.setState({shortURL, loading: false})) diff --git a/website/src/pages/docs/index.js b/website/src/pages/docs/index.js index 66e0a363..96dee1ae 100644 --- a/website/src/pages/docs/index.js +++ b/website/src/pages/docs/index.js @@ -49,17 +49,16 @@ export default ({data}) => ( ({node}) => node.fileAbsolutePath.indexOf(`/${category}/`) > -1, ) - .map( - ({node}) => - node.frontmatter.redirect ? ( - - {node.frontmatter.title} - - ) : ( - - {node.frontmatter.title} - - ), + .map(({node}) => + node.frontmatter.redirect ? ( + + {node.frontmatter.title} + + ) : ( + + {node.frontmatter.title} + + ), )} ), From e5743e851bde6611529a8c57401ad6445ca57b32 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Tue, 14 Apr 2020 02:04:17 -0700 Subject: [PATCH 34/87] Set width/height also to Undefined when we change the measure mode to Undefined Summary: Make sure width/height is always passed as Undefined when measure mode is changed to Undefined. Changelog: [Internal][Yoga] Set width and height as Undefined when we change measure mode to Undefined Reviewed By: alickbass Differential Revision: D20029838 fbshipit-source-id: b9931f6ddb13ffd1565889535ade5bbffbe0c304 --- yoga/Yoga.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index d916a45f..d6f4a114 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1663,8 +1663,8 @@ static void YGNodeAbsoluteLayoutChild( static void YGNodeWithMeasureFuncSetMeasuredDimensions( const YGNodeRef node, - const float availableWidth, - const float availableHeight, + float availableWidth, + float availableHeight, const YGMeasureMode widthMeasureMode, const YGMeasureMode heightMeasureMode, const float ownerWidth, @@ -1677,6 +1677,13 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( node->hasMeasureFunc(), "Expected node to have custom measure function"); + if (widthMeasureMode == YGMeasureModeUndefined) { + availableWidth = YGUndefined; + } + if (heightMeasureMode == YGMeasureModeUndefined) { + availableHeight = YGUndefined; + } + const float paddingAndBorderAxisRow = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); const float paddingAndBorderAxisColumn = From 9b96a5362a873935c50b444aa271927257c2f984 Mon Sep 17 00:00:00 2001 From: empyrical Date: Tue, 14 Apr 2020 16:39:32 -0700 Subject: [PATCH 35/87] Yoga Podspec: Export YGNode and YGStyle headers (#997) Summary: This pull request adds `YGNode.h` and `YGStyle.h` to the headers exported by Yoga's podspec. They are required by the new Fabric architecture of React Native. The modulemap and its umbrella header automatically generated by Cocoapods adds all exported headers to the `modulemap`. Having YGNode and YGStyle exported through here has problems, because they are only available in environments that have C++ available, and will produce errors otherwise. This pull request fences off the contents of those headers in an `#ifdef __cplusplus` block, so they will not cause errors when imported into environments where C++ isn't available. I had considered adding a custom modulemap to the podspec as part of this pull request, but this way seems the least "invasive", and this way you are able to add and remove exported headers in the podspec without needing to worry about updating the umbrella header at the same time. Changelog: [Internal] - Yoga Podspec: Export YGNore and YGStyle headers Pull Request resolved: https://github.com/facebook/yoga/pull/997 Reviewed By: hramos Differential Revision: D20966075 Pulled By: mdvacca fbshipit-source-id: 5f5caa6b639d11e660b968d681da9a4de6c0eb8e --- Yoga.podspec | 2 +- yoga/YGNode.h | 5 +++++ yoga/YGStyle.h | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Yoga.podspec b/Yoga.podspec index 24e1c0b8..2b09977d 100644 --- a/Yoga.podspec +++ b/Yoga.podspec @@ -33,6 +33,6 @@ Pod::Spec.new do |spec| '-fPIC' ] spec.source_files = 'yoga/**/*.{c,h,cpp}' - spec.public_header_files = 'yoga/{Yoga,YGEnums,YGMacros,YGValue}.h' + spec.public_header_files = 'yoga/{Yoga,YGEnums,YGMacros,YGNode,YGStyle,YGValue}.h' end diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 9aef1ec6..63d98fe3 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -6,6 +6,9 @@ */ #pragma once + +#ifdef __cplusplus + #include #include #include "BitUtils.h" @@ -330,3 +333,5 @@ public: bool isLayoutTreeEqualToNode(const YGNode& node) const; void reset(); }; + +#endif diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h index 9bfbc442..aab7599c 100644 --- a/yoga/YGStyle.h +++ b/yoga/YGStyle.h @@ -6,6 +6,9 @@ */ #pragma once + +#ifdef __cplusplus + #include #include #include @@ -229,3 +232,5 @@ YOGA_EXPORT bool operator==(const YGStyle& lhs, const YGStyle& rhs); YOGA_EXPORT inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) { return !(lhs == rhs); } + +#endif From e637cf2d72654d4b125e84de86bbcd2f30604cf6 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Wed, 15 Apr 2020 00:47:07 -0700 Subject: [PATCH 36/87] Add Yoga also as a dependency of testutil-jni Summary: `scripts/deploy_jcenter.sh` was failing {F234018047} Added `yoga` also as a dependency of `testutil-jni` Reviewed By: gavinweng Differential Revision: D21017796 fbshipit-source-id: 0c34e7fc2373906441bd7805f5687b2c5dab6242 --- testutil/BUCK | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testutil/BUCK b/testutil/BUCK index acbabc11..1a66f91b 100644 --- a/testutil/BUCK +++ b/testutil/BUCK @@ -20,7 +20,10 @@ yoga_cxx_library( platforms = ANDROID, soname = "libyoga_testutil.$(ext)", visibility = ["PUBLIC"], - deps = [yoga_dep("java:jni")], + deps = [ + yoga_dep("java:jni"), + yoga_dep(":yoga"), + ], ) yoga_java_library( From 92b76447b772e39d4ac209d25f123e9655be2f62 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 17 Apr 2020 05:25:22 -0700 Subject: [PATCH 37/87] use default value of enums YGDirection and YGMeasureMode instead of -1 Summary: Changelog: [Internal][Yoga] YGDirection variable was initialized incorrectly by casting -1 to YGDirection. Changing it to default value of direction Same for YGMeasureMode. Reviewed By: pasqualeanatriello Differential Revision: D20869042 fbshipit-source-id: 7bfe490193321baae875ef6fb49a938851950c9f --- yoga/YGLayout.h | 2 +- yoga/Yoga-internal.h | 8 ++++---- yoga/Yoga.cpp | 6 ++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/yoga/YGLayout.h b/yoga/YGLayout.h index 30b8dd76..b7604d8e 100644 --- a/yoga/YGLayout.h +++ b/yoga/YGLayout.h @@ -36,7 +36,7 @@ public: // Instead of recomputing the entire layout every single time, we cache some // information to break early when nothing changed uint32_t generationCount = 0; - YGDirection lastOwnerDirection = (YGDirection) -1; + YGDirection lastOwnerDirection = YGDirectionInherit; uint32_t nextCachedMeasurementsIndex = 0; std::array diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 0b3368a0..1a22f24c 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -54,10 +54,10 @@ struct YGCachedMeasurement { float computedHeight; YGCachedMeasurement() - : availableWidth(0), - availableHeight(0), - widthMeasureMode((YGMeasureMode) -1), - heightMeasureMode((YGMeasureMode) -1), + : availableWidth(-1), + availableHeight(-1), + widthMeasureMode(YGMeasureModeUndefined), + heightMeasureMode(YGMeasureModeUndefined), computedWidth(-1), computedHeight(-1) {} diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index d6f4a114..bb7da7bf 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -3821,8 +3821,10 @@ bool YGLayoutNodeInternal( if (needToVisitNode) { // Invalidate the cached results. layout->nextCachedMeasurementsIndex = 0; - layout->cachedLayout.widthMeasureMode = (YGMeasureMode) -1; - layout->cachedLayout.heightMeasureMode = (YGMeasureMode) -1; + layout->cachedLayout.availableWidth = -1; + layout->cachedLayout.availableHeight = -1; + layout->cachedLayout.widthMeasureMode = YGMeasureModeUndefined; + layout->cachedLayout.heightMeasureMode = YGMeasureModeUndefined; layout->cachedLayout.computedWidth = -1; layout->cachedLayout.computedHeight = -1; } From 1bd4123df1e493990fe96ab5bc459edfb5dada3b Mon Sep 17 00:00:00 2001 From: acton393 Date: Fri, 17 Apr 2020 05:43:28 -0700 Subject: [PATCH 38/87] fix typo as there is no file called YGJNI.cpp (#990) Summary: fix typo in `YogaJNIBase.java` as there is no such file called `YGJNI.cpp` Pull Request resolved: https://github.com/facebook/yoga/pull/990 Reviewed By: pasqualeanatriello Differential Revision: D20735102 Pulled By: SidharthGuglani fbshipit-source-id: 3f9f4d78ba390feae3451330f997a221ab4ec70e --- java/com/facebook/yoga/YogaNodeJNIBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com/facebook/yoga/YogaNodeJNIBase.java b/java/com/facebook/yoga/YogaNodeJNIBase.java index e20a5389..406e75e5 100644 --- a/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -15,7 +15,7 @@ import javax.annotation.Nullable; @DoNotStrip public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { - /* Those flags needs be in sync with YGJNI.cpp */ + /* Those flags needs be in sync with YGJNI.h */ private static final byte MARGIN = 1; private static final byte PADDING = 2; private static final byte BORDER = 4; From a96a36ef592eefc206053b95f4ace080f251850a Mon Sep 17 00:00:00 2001 From: Gavin Weng Date: Fri, 17 Apr 2020 17:31:39 -0700 Subject: [PATCH 39/87] Link yogacore statically into yoga Summary: A revert of D20879886. Reviewed By: iliagore Differential Revision: D20979490 fbshipit-source-id: cb37f931654450c408e72578abcc549f35727b07 --- java/BUCK | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/BUCK b/java/BUCK index 034024cd..d08cb37b 100644 --- a/java/BUCK +++ b/java/BUCK @@ -54,7 +54,7 @@ yoga_cxx_library( visibility = ["PUBLIC"], deps = [ JNI_TARGET, - yoga_dep(":yoga"), + yoga_dep(":yoga-static"), ":ndklog", ], ) From 884f147742771cea14fcfb1f4ac485b187e7c3fe Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 20 Apr 2020 12:01:56 -0700 Subject: [PATCH 40/87] Fixed incorrect owner assignment in YGNode move constructor Summary: Assigning self as an owner makes a cycle which is obviously a bug. Changelog: [Internal] Small change in Yoga (should not affect RN). Reviewed By: SidharthGuglani Differential Revision: D21111423 fbshipit-source-id: 1835561c055ac827f5ce98a044f25aed0d1845a5 --- yoga/YGNode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index c15af8de..23d5c40b 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -29,7 +29,7 @@ YGNode::YGNode(YGNode&& node) { config_ = node.config_; resolvedDimensions_ = node.resolvedDimensions_; for (auto c : children_) { - c->setOwner(c); + c->setOwner(this); } } From 83b27417ae6a1d577b1fddfa3c9433c2dc42a460 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Mon, 27 Apr 2020 14:38:51 -0700 Subject: [PATCH 41/87] Fix rounding error using double instead of float Summary: Changelog: [Internal] [Yoga] Use double instead of float during rounding process to prevent loss of precision. Reviewed By: mdvacca Differential Revision: D21227565 fbshipit-source-id: 380b57535a356624cda8dc2017871a4ef3c882d1 --- yoga/Yoga.cpp | 26 +++++++++++++------------- yoga/Yoga.h | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index bb7da7bf..c2a5c286 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -3664,8 +3664,8 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid( } YOGA_EXPORT float YGRoundValueToPixelGrid( - const float value, - const float pointScaleFactor, + const double value, + const double pointScaleFactor, const bool forceCeil, const bool forceFloor) { double scaledValue = ((double) value) * pointScaleFactor; @@ -4081,24 +4081,24 @@ YOGA_EXPORT void YGConfigSetPointScaleFactor( static void YGRoundToPixelGrid( const YGNodeRef node, - const float pointScaleFactor, - const float absoluteLeft, - const float absoluteTop) { + const double pointScaleFactor, + const double absoluteLeft, + const double absoluteTop) { if (pointScaleFactor == 0.0f) { return; } - const float nodeLeft = node->getLayout().position[YGEdgeLeft]; - const float nodeTop = node->getLayout().position[YGEdgeTop]; + const double nodeLeft = node->getLayout().position[YGEdgeLeft]; + const double nodeTop = node->getLayout().position[YGEdgeTop]; - const float nodeWidth = node->getLayout().dimensions[YGDimensionWidth]; - const float nodeHeight = node->getLayout().dimensions[YGDimensionHeight]; + const double nodeWidth = node->getLayout().dimensions[YGDimensionWidth]; + const double nodeHeight = node->getLayout().dimensions[YGDimensionHeight]; - const float absoluteNodeLeft = absoluteLeft + nodeLeft; - const float absoluteNodeTop = absoluteTop + nodeTop; + const double absoluteNodeLeft = absoluteLeft + nodeLeft; + const double absoluteNodeTop = absoluteTop + nodeTop; - const float absoluteNodeRight = absoluteNodeLeft + nodeWidth; - const float absoluteNodeBottom = absoluteNodeTop + nodeHeight; + const double absoluteNodeRight = absoluteNodeLeft + nodeWidth; + const double absoluteNodeBottom = absoluteNodeTop + nodeHeight; // If a node has a custom measure function we never want to round down its // size as this could lead to unwanted text truncation. diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 2fe60a41..87901a28 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -352,8 +352,8 @@ WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context); WIN_EXPORT void* YGConfigGetContext(YGConfigRef config); WIN_EXPORT float YGRoundValueToPixelGrid( - float value, - float pointScaleFactor, + double value, + double pointScaleFactor, bool forceCeil, bool forceFloor); From ac7c85c0a629e5029d7e36304d4c02c71da0f41a Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Tue, 12 May 2020 11:44:50 -0700 Subject: [PATCH 42/87] Migrate CI from TravisCI to GitHub Actions (#1004) Summary: Migrate from TravisCI to GitHub Actions. Facebook employees can read about this migration [here](https://fburl.com/rfp033ou). CC: wittgenst Pull Request resolved: https://github.com/facebook/yoga/pull/1004 Test Plan: GitHub Actions CI on my personal GitHub: https://github.com/bigfootjon/yoga/runs/653755729 Reviewed By: passy Differential Revision: D21431309 Pulled By: bigfootjon fbshipit-source-id: 490a8679bc0cfec26b13c8c584a928f03c6e26e7 --- .github/workflows/ci.yml | 56 +++++++++++++++++++++++++++ .travis.yml | 77 ------------------------------------- scripts/publish-snapshot.sh | 12 +++--- 3 files changed, 62 insertions(+), 83 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..ccb6b297 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,56 @@ +name: CI + +on: [push, pull_request] + +jobs: + website: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v1 + with: + node-version: 8.x + - name: Install dependencies + run: yarn install --frozen-lockfile --ignore-scripts + working-directory: website + - name: Build + run: yarn build + working-directory: website + - name: Deploy + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_branch: gh-pages + publish_dir: website/public + cname: yogalayout.com + keep_files: true + user_name: 'Yoga-bot' + user_email: 'yogabot@fb.com' + android: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: | + if [[ -n "$encrypted_d27e803291ff_iv" ]]; then + openssl aes-256-cbc -K $encrypted_d27e803291ff_key -iv $encrypted_d27e803291ff_iv -in scripts/setup-keys.enc -d >> gradle.properties; + fi + sudo apt-get update + sudo apt-get install -y ninja-build + pushd $HOME + git clone --depth 1 https://github.com/facebook/buck.git + cd buck + ant + popd + echo "::set-env name=PATH::$PATH:$HOME/buck/bin/" + export PATH=$PATH:$HOME/buck/bin/ + buck --version + export TERMINAL=dumb + source scripts/android-setup.sh && installAndroidSDK + echo "::set-env name=ANDROID_SDK::$ANDROID_HOME" + echo "::set-env name=ANDROID_NDK_REPOSITORY::$HOME/android-ndk" + echo "::set-env name=ANDROID_NDK_HOME::$ANDROID_NDK_REPOSITORY/android-ndk-r15c" + - name: Build + run: ./gradlew testDebugUnit && scripts/publish-snapshot.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3ae55d1f..00000000 --- a/.travis.yml +++ /dev/null @@ -1,77 +0,0 @@ -language: java -os: linux -dist: trusty -addons: - apt: - sources: - - llvm-toolchain-trusty-6.0 - - ubuntu-toolchain-r-test - packages: - - clang-6.0 - -env: - - TARGET: website - - TARGET: android - -install: -- cd website -- yarn --ignore-scripts -- cd .. - -cache: - directories: - - $HOME/buck - - $HOME/.gradle - -before_install: - - | - if [[ -n "$encrypted_d27e803291ff_iv" ]]; then - openssl aes-256-cbc -K $encrypted_d27e803291ff_key -iv $encrypted_d27e803291ff_iv -in scripts/setup-keys.enc -d >> gradle.properties; - fi - # Android - - | - if [[ $TARGET = "android" ]]; then - pushd $HOME - git clone --depth 1 https://github.com/facebook/buck.git - cd buck - ant - popd - export PATH=$PATH:$HOME/buck/bin/ - buck --version - export TERMINAL=dumb - source scripts/android-setup.sh && installAndroidSDK - export ANDROID_SDK=$ANDROID_HOME - export ANDROID_NDK_REPOSITORY=$HOME/android-ndk - export ANDROID_NDK_HOME=$ANDROID_NDK_REPOSITORY/android-ndk-r15c - fi - # Website - - | - if [[ $TARGET = "website" ]]; then - nvm install 8 - nvm use 8 - fi - -script: - - | - if [[ $TARGET = "android" ]]; then - ./gradlew testDebugUnit && scripts/publish-snapshot.sh - fi - - | - if [[ $TARGET = "website" ]]; then - pushd website - yarn build - popd - fi - -deploy: - provider: pages - skip-cleanup: true - github-token: $GITHUB_TOKEN - fqdn: yogalayout.com - local-dir: website/public - email: yogabot@fb.com - name: Yoga-bot - keep-history: true - on: - branch: master - condition: $TARGET = website diff --git a/scripts/publish-snapshot.sh b/scripts/publish-snapshot.sh index 02c45457..c494f97f 100755 --- a/scripts/publish-snapshot.sh +++ b/scripts/publish-snapshot.sh @@ -14,14 +14,14 @@ set -e BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" IS_SNAPSHOT="$(grep 'VERSION_NAME=[0-9\.]\+-SNAPSHOT' "$BASEDIR/gradle.properties")" -if [ "$TRAVIS_REPO_SLUG" != "facebook/yoga" ]; then - echo >&2 "Skipping repository. Expected project to be 'facebook/yoga', but was '$TRAVIS_REPO_SLUG'." +if [ "$GITHUB_REPOSITORY" != "facebook/yoga" ]; then + echo >&2 "Skipping repository. Expected project to be 'facebook/yoga', but was '$GITHUB_REPOSITORY'." exit -elif [ "$TRAVIS_BRANCH" != "master" ]; then - echo >&2 "Skipping build. Expected branch name to be 'master', but was '$TRAVIS_BRANCH'." +elif [ "$GITHUB_REF" != "refs/heads/master" ]; then + echo >&2 "Skipping build. Expected ref name to be 'refs/heads/master', but was '$GITHUB_REF'." exit -elif [ "$TRAVIS_PULL_REQUEST" != "false" ]; then - echo >&2 "Skipping build. Only considering non-PR builds, but URL was '$TRAVIS_PULL_REQUEST'." +elif [ "$GITHUB_EVENT_NAME" != "push" ]; then + echo >&2 "Skipping build. Only considering push builds, but event was '$GITHUB_EVENT_NAME'." exit elif [ "$IS_SNAPSHOT" == "" ]; then echo >&2 "Skipping build. Given build doesn't appear to be a SNAPSHOT release." From 07c0d539bdb3a248762d0a06fd3f622b278a7ecb Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Thu, 14 May 2020 06:32:13 -0700 Subject: [PATCH 43/87] throw std::logic_error instead of aborting the process and convert to java exception Summary: Changelog: [Internal][Yoga] throw std::logic_error instead of aborting the process and convert to java exception for jni layer Reviewed By: pasqualeanatriello Differential Revision: D21301235 fbshipit-source-id: 148b27920e62990a271e1d0df8c85a2cc42f4fd4 --- java/jni/YGJNIVanilla.cpp | 7 +++++++ tests/YGMeasureTest.cpp | 4 ++-- yoga/Utils.cpp | 4 ++++ yoga/Utils.h | 2 ++ yoga/Yoga.cpp | 6 +++--- yoga/log.cpp | 4 ---- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index 6e66c06e..698ab561 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -388,6 +388,13 @@ static void jni_YGNodeCalculateLayoutJNI( if (throwable.get()) { env->Throw(throwable.get()); } + } catch (const std::logic_error& ex) { + env->ExceptionClear(); + jclass cl = env->FindClass("Ljava/lang/IllegalStateException;"); + static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( + env, cl, "", "(Ljava/lang/String;)V"); + auto throwable = env->NewObject(cl, methodId, env->NewStringUTF(ex.what())); + env->Throw(static_cast(throwable)); } } diff --git a/tests/YGMeasureTest.cpp b/tests/YGMeasureTest.cpp index b5bbe5d4..e47607d4 100644 --- a/tests/YGMeasureTest.cpp +++ b/tests/YGMeasureTest.cpp @@ -580,7 +580,7 @@ TEST(YogaDeathTest, cannot_add_child_to_node_with_measure_func) { root->setMeasureFunc(_measure); const YGNodeRef root_child0 = YGNodeNew(); - ASSERT_DEATH(YGNodeInsertChild(root, root_child0, 0), "Cannot add child.*"); + ASSERT_THROW(YGNodeInsertChild(root, root_child0, 0), std::logic_error); YGNodeFree(root_child0); YGNodeFreeRecursive(root); } @@ -589,7 +589,7 @@ TEST(YogaDeathTest, cannot_add_nonnull_measure_func_to_non_leaf_node) { const YGNodeRef root = YGNodeNew(); const YGNodeRef root_child0 = YGNodeNew(); YGNodeInsertChild(root, root_child0, 0); - ASSERT_DEATH(root->setMeasureFunc(_measure), "Cannot set measure function.*"); + ASSERT_THROW(root->setMeasureFunc(_measure), std::logic_error); YGNodeFreeRecursive(root); } diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index 761f3515..f6e55d0d 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -65,3 +65,7 @@ YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) { } return op1.isUndefined() ? op2 : op1; } + +void throwLogicalErrorWithMessage(const char* message) { + throw std::logic_error(message); +} diff --git a/yoga/Utils.h b/yoga/Utils.h index bce8dfca..e9edf2f9 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -141,3 +141,5 @@ inline YGFloatOptional YGResolveValueMargin( const float ownerSize) { return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize); } + +void throwLogicalErrorWithMessage(const char* message); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index c2a5c286..91e09c15 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -249,9 +249,6 @@ YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) { static YGConfigRef YGConfigClone(const YGConfig& oldConfig) { const YGConfigRef config = new YGConfig(oldConfig); YGAssert(config != nullptr, "Could not allocate memory for config"); - if (config == nullptr) { - abort(); - } gConfigInstanceCount++; return config; } @@ -4341,6 +4338,7 @@ YOGA_EXPORT void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( void YGAssert(const bool condition, const char* message) { if (!condition) { Log::log(YGNodeRef{nullptr}, YGLogLevelFatal, nullptr, "%s\n", message); + throwLogicalErrorWithMessage(message); } } @@ -4350,6 +4348,7 @@ void YGAssertWithNode( const char* message) { if (!condition) { Log::log(node, YGLogLevelFatal, nullptr, "%s\n", message); + throwLogicalErrorWithMessage(message); } } @@ -4359,6 +4358,7 @@ void YGAssertWithConfig( const char* message) { if (!condition) { Log::log(config, YGLogLevelFatal, nullptr, "%s\n", message); + throwLogicalErrorWithMessage(message); } } diff --git a/yoga/log.cpp b/yoga/log.cpp index fe6fbbc6..eb3da039 100644 --- a/yoga/log.cpp +++ b/yoga/log.cpp @@ -26,10 +26,6 @@ void vlog( va_list args) { YGConfig* logConfig = config != nullptr ? config : YGConfigGetDefault(); logConfig->log(logConfig, node, level, context, format, args); - - if (level == YGLogLevelFatal) { - abort(); - } } } // namespace From 4135420cba9540c2d5157dc42fecace4df59af45 Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Thu, 14 May 2020 12:19:37 -0700 Subject: [PATCH 44/87] Fix GitHub Actions secrets access (#1005) Summary: Ref: [Secrets documentation](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#using-encrypted-secrets-in-a-workflow) In combination with setting the secrets in the GitHub settings, this should fully migrate yoga to GH actions. Pull Request resolved: https://github.com/facebook/yoga/pull/1005 Test Plan: GitHub Actions CI on the PR attached to this diff Reviewed By: SidharthGuglani Differential Revision: D21574995 Pulled By: bigfootjon fbshipit-source-id: e9ee6d7cf1ae131afdc3aa3778667f1e9b9de833 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccb6b297..c5f2c014 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,8 +34,8 @@ jobs: - uses: actions/checkout@v2 - name: Install dependencies run: | - if [[ -n "$encrypted_d27e803291ff_iv" ]]; then - openssl aes-256-cbc -K $encrypted_d27e803291ff_key -iv $encrypted_d27e803291ff_iv -in scripts/setup-keys.enc -d >> gradle.properties; + if [[ -n "${{ secrets.encrypted_d27e803291ff_iv }}" ]]; then + openssl aes-256-cbc -K ${{ secrets.encrypted_d27e803291ff_key }} -iv {{ secrets.encrypted_d27e803291ff_iv }} -in scripts/setup-keys.enc -d >> gradle.properties; fi sudo apt-get update sudo apt-get install -y ninja-build From ede65bbce4a45aa62d7cb78c8786a2c0eea69661 Mon Sep 17 00:00:00 2001 From: Steven Koeber Date: Thu, 4 Jun 2020 06:35:13 -0700 Subject: [PATCH 45/87] Buckification of Yoga build script Reviewed By: liorisraeli87, k21 Differential Revision: D21429174 fbshipit-source-id: f12c8349cc59398553773df7bc15f0f83bd571b4 --- lib/soloader/BUCK | 5 ++--- tools/build_defs/oss/yoga_defs.bzl | 3 +++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/soloader/BUCK b/lib/soloader/BUCK index 04e2f5ff..eaff4f68 100644 --- a/lib/soloader/BUCK +++ b/lib/soloader/BUCK @@ -3,10 +3,9 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") -load("//tools/build_defs/oss:yoga_defs.bzl", "YOGA_ROOTS") +load("//tools/build_defs/oss:yoga_defs.bzl", "YOGA_ROOTS", "yoga_prebuilt_aar") -fb_native.android_prebuilt_aar( +yoga_prebuilt_aar( name = "soloader", aar = "soloader-0.5.1.aar", visibility = YOGA_ROOTS, diff --git a/tools/build_defs/oss/yoga_defs.bzl b/tools/build_defs/oss/yoga_defs.bzl index 253449b3..2c108c20 100644 --- a/tools/build_defs/oss/yoga_defs.bzl +++ b/tools/build_defs/oss/yoga_defs.bzl @@ -202,6 +202,9 @@ def yoga_prebuilt_cxx_library(*args, **kwargs): def yoga_prebuilt_jar(*args, **kwargs): native.prebuilt_jar(*args, **kwargs) +def yoga_prebuilt_aar(*args, **kwargs): + native.android_prebuilt_aar(*args, **kwargs) + def is_apple_platform(): return True From 633cdc908857a580e73bc209864cc227e25f78b4 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Mon, 8 Jun 2020 08:07:37 -0700 Subject: [PATCH 46/87] use fmod and YGDoubleEquals for double operations instead of float Summary: Changelog: [Internal][Yoga] Use double operations during rounding Reviewed By: mdvacca Differential Revision: D21840018 fbshipit-source-id: c5d17fcb8984b1da9832a15ccd4d628e8d742c6a --- yoga/Utils.cpp | 7 +++++++ yoga/Utils.h | 2 ++ yoga/Yoga.cpp | 16 ++++++++-------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index f6e55d0d..c4281b60 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -52,6 +52,13 @@ bool YGFloatsEqual(const float a, const float b) { return yoga::isUndefined(a) && yoga::isUndefined(b); } +bool YGDoubleEqual(const double a, const double b) { + if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { + return fabs(a - b) < 0.0001f; + } + return yoga::isUndefined(a) && yoga::isUndefined(b); +} + float YGFloatSanitize(const float val) { return yoga::isUndefined(val) ? 0 : val; } diff --git a/yoga/Utils.h b/yoga/Utils.h index e9edf2f9..57e1d45d 100644 --- a/yoga/Utils.h +++ b/yoga/Utils.h @@ -64,6 +64,8 @@ inline bool YGValueEqual( // difference between two floats is less than 0.0001f or both are undefined. bool YGFloatsEqual(const float a, const float b); +bool YGDoubleEqual(const double a, const double b); + float YGFloatMax(const float a, const float b); YGFloatOptional YGFloatOptionalMax( diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 91e09c15..cb06c10e 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -3668,7 +3668,7 @@ YOGA_EXPORT float YGRoundValueToPixelGrid( double scaledValue = ((double) value) * pointScaleFactor; // We want to calculate `fractial` such that `floor(scaledValue) = scaledValue // - fractial`. - float fractial = fmodf(scaledValue, 1.0f); + double fractial = fmod(scaledValue, 1.0f); if (fractial < 0) { // This branch is for handling negative numbers for `value`. // @@ -3687,10 +3687,10 @@ YOGA_EXPORT float YGRoundValueToPixelGrid( // - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3 ++fractial; } - if (YGFloatsEqual(fractial, 0)) { + if (YGDoubleEqual(fractial, 0)) { // First we check if the value is already rounded scaledValue = scaledValue - fractial; - } else if (YGFloatsEqual(fractial, 1.0f)) { + } else if (YGDoubleEqual(fractial, 1.0f)) { scaledValue = scaledValue - fractial + 1.0f; } else if (forceCeil) { // Next we check if we need to use forced rounding @@ -3701,7 +3701,7 @@ YOGA_EXPORT float YGRoundValueToPixelGrid( // Finally we just round the value scaledValue = scaledValue - fractial + (!YGFloatIsUndefined(fractial) && - (fractial > 0.5f || YGFloatsEqual(fractial, 0.5f)) + (fractial > 0.5f || YGDoubleEqual(fractial, 0.5f)) ? 1.0f : 0.0f); } @@ -4113,11 +4113,11 @@ static void YGRoundToPixelGrid( // whole number, we don't have any fraction To verify if the result is close // to whole number we want to check both floor and ceil numbers const bool hasFractionalWidth = - !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 0) && - !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 1.0); + !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 0) && + !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0); const bool hasFractionalHeight = - !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 0) && - !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 1.0); + !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 0) && + !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0); node->setLayoutDimension( YGRoundValueToPixelGrid( From d74a1069a03c5e184209a43e883b406786d8bbd0 Mon Sep 17 00:00:00 2001 From: Stiopa Koltsov Date: Wed, 24 Jun 2020 12:15:15 -0700 Subject: [PATCH 47/87] xplat: Disable Starlark in several files Summary: Disable Starlark in several files which are not trivial to fix. Reviewed By: scottrice Differential Revision: D22202463 fbshipit-source-id: a3ff717f0f4b9cd7f492b8fcebdb91f232207222 --- java/BUCK | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/BUCK b/java/BUCK index d08cb37b..a658d7e9 100644 --- a/java/BUCK +++ b/java/BUCK @@ -1,3 +1,5 @@ +# BUILD FILE SYNTAX: PYTHON_DSL + # Copyright (c) Facebook, Inc. and its affiliates. # # This source code is licensed under the MIT license found in the From a93e5d63c9d26e378c07f3adfd86e16a4ca88143 Mon Sep 17 00:00:00 2001 From: Amir Shalem Date: Mon, 6 Jul 2020 03:41:19 -0700 Subject: [PATCH 48/87] Don't call config->setLogger(nullptr) directly to avoid having no logger at all Summary: Changelog: [Internal][Yoga] Don't call config->setLogger(nullptr) directly to avoid having no logger at all Broken in D14151037 (https://github.com/facebook/yoga/commit/05f36a835a3a66b1b8affcdb036ec47117a8d28f) when it started calling ``` config->setLogger(nullptr); ``` instead of going thru ``` YGConfigSetLogger(config, nullptr); ``` which does the right thing by setting the logger to its default value: https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/xplat/yoga/yoga/Yoga.cpp?commit=835911317e8b3cf7da1866e40e1c79cda0690136&lines=4320-4330 Also by default YogaConfig always have a logger: https://www.internalfb.com/intern/diffusion/FBS/browsefile/master/xplat/yoga/yoga/Yoga.cpp?commit=835911317e8b3cf7da1866e40e1c79cda0690136&lines=335-343 Reviewed By: SidharthGuglani Differential Revision: D22387459 fbshipit-source-id: 4da91da87a696d38cc9d8db2acb5845d29398adb --- java/jni/YGJNIVanilla.cpp | 2 +- .../com/facebook/yoga/YogaLoggerTest.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index 698ab561..65343821 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -196,7 +196,7 @@ static void jni_YGConfigSetLoggerJNI( delete context; YGConfigSetContext(config, nullptr); } - config->setLogger(nullptr); + YGConfigSetLogger(config, nullptr); } } diff --git a/java/tests/com/facebook/yoga/YogaLoggerTest.java b/java/tests/com/facebook/yoga/YogaLoggerTest.java index 17316f6e..f88409d6 100644 --- a/java/tests/com/facebook/yoga/YogaLoggerTest.java +++ b/java/tests/com/facebook/yoga/YogaLoggerTest.java @@ -9,10 +9,62 @@ package com.facebook.yoga; import org.junit.Test; import java.lang.ref.WeakReference; +import java.util.List; +import java.util.ArrayList; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class YogaLoggerTest { + + @Test + public void testRemovingLoggerFromConfig() throws Exception { + final List logs = new ArrayList<>(); + + final YogaConfig config = YogaConfigFactory.create(); + YogaLogger logger = new YogaLogger() { + @Override + public void log(YogaLogLevel level, String message) { + logs.add(message); + } + }; + config.setLogger(logger); + + final YogaNode root = YogaNodeFactory.create(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + + final YogaNode child1 = YogaNodeFactory.create(config); + root.addChildAt(child1, 0); + + final YogaNode child2 = YogaNodeFactory.create(config); + child2.setBaselineFunction(new YogaBaselineFunction() { + public float baseline(YogaNode node, float width, float height) { + return Float.NaN; + } + }); + root.addChildAt(child2, 1); + + assertEquals(logs.size(), 0); + try { + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + fail("Expected calculateLayout to throw"); + } catch (IllegalStateException e) { + } + + assertEquals(logs.size(), 1); + + config.setLogger(null); + + try { + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + fail("Expected calculateLayout to throw again"); + } catch (IllegalStateException e) { + } + + assertEquals(logs.size(), 1); + } + @Test public void testLoggerLeak() throws Exception { final YogaConfig config = YogaConfigFactory.create(); From 0767f4d10522677a0254613b8fe6466bc3b29534 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 14 Jul 2020 15:20:24 -0700 Subject: [PATCH 49/87] Using `YGPositionTypeAbsolute` value where we compare `absolute` vs `relative` Summary: Now Yoga.cpp does not use the `YGPositionTypeRelative` value/constant, it uses `YGPositionTypeAbsolute` instead. Now `YGPositionType` can only be `YGPositionTypeRelative` or `YGPositionTypeAbsolute`, so expressions `x == YGPositionTypeRelative` and `x != YGPositionTypeAbsolute` are equivalent. The reasoning behind the change is that in all cases we actually check a node to be (or not to be) `absolute`, not `relative`. This will make a difference in the coming diffs in the stack when we will introduce a new value for the type: `static`. We need to differentiate `static` and `relative` values t implement the `stacking context` feature in the W3C-compliant way (to fix bugs and avoid developer confusion). Read more here: https://developer.mozilla.org/en-US/docs/Web/CSS/position Changelog: [Internal] Internal change in Yoga. Reviewed By: SidharthGuglani Differential Revision: D22386733 fbshipit-source-id: 8e2c2b88b404660639f845783c8f93f0c62c0fbb --- yoga/YGNode.cpp | 5 ++++- yoga/Yoga.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 23d5c40b..1ee1bde6 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -307,6 +307,9 @@ void YGNode::setPosition( const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, directionRespectingRoot); + // Here we should check for `YGPositionTypeStatic` and in this case zero inset + // properties (left, right, top, bottom, begin, end). + // https://www.w3.org/TR/css-position-3/#valdef-position-static const YGFloatOptional relativePositionMain = relativePosition(mainAxis, mainSize); const YGFloatOptional relativePositionCross = @@ -440,7 +443,7 @@ float YGNode::resolveFlexShrink() const { bool YGNode::isNodeFlexible() { return ( - (style_.positionType() == YGPositionTypeRelative) && + (style_.positionType() != YGPositionTypeAbsolute) && (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); } diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index cb06c10e..97e64075 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1131,7 +1131,7 @@ static bool YGIsBaselineLayout(const YGNodeRef node) { const uint32_t childCount = YGNodeGetChildCount(node); for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef child = YGNodeGetChild(node, i); - if (child->getStyle().positionType() == YGPositionTypeRelative && + if (child->getStyle().positionType() != YGPositionTypeAbsolute && child->getStyle().alignSelf() == YGAlignBaseline) { return true; } @@ -2505,7 +2505,7 @@ static void YGJustifyMainAxis( i < collectedFlexItemsValues.endOfLineIndex; i++) { const YGNodeRef child = node->getChild(i); - if (child->getStyle().positionType() == YGPositionTypeRelative) { + if (child->getStyle().positionType() != YGPositionTypeAbsolute) { if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) { numberOfAutoMarginsOnCurrentLine++; } @@ -2589,7 +2589,7 @@ static void YGJustifyMainAxis( // Now that we placed the element, we need to update the variables. // We need to do that only for relative elements. Absolute elements do not // take part in that phase. - if (childStyle.positionType() == YGPositionTypeRelative) { + if (childStyle.positionType() != YGPositionTypeAbsolute) { if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) { collectedFlexItemsValues.mainDim += collectedFlexItemsValues.remainingFreeSpace / @@ -3311,7 +3311,7 @@ static void YGNodelayoutImpl( if (child->getStyle().display() == YGDisplayNone) { continue; } - if (child->getStyle().positionType() == YGPositionTypeRelative) { + if (child->getStyle().positionType() != YGPositionTypeAbsolute) { if (child->getLineIndex() != i) { break; } @@ -3353,7 +3353,7 @@ static void YGNodelayoutImpl( if (child->getStyle().display() == YGDisplayNone) { continue; } - if (child->getStyle().positionType() == YGPositionTypeRelative) { + if (child->getStyle().positionType() != YGPositionTypeAbsolute) { switch (YGNodeAlignItem(node, child)) { case YGAlignFlexStart: { child->setLayoutPosition( @@ -3544,7 +3544,7 @@ static void YGNodelayoutImpl( if (performLayout && node->getStyle().flexWrap() == YGWrapWrapReverse) { for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef child = YGNodeGetChild(node, i); - if (child->getStyle().positionType() == YGPositionTypeRelative) { + if (child->getStyle().positionType() != YGPositionTypeAbsolute) { child->setLayoutPosition( node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().position[pos[crossAxis]] - From 16f676eccff0da229ba9ab97c96c4973b01b6750 Mon Sep 17 00:00:00 2001 From: Stanislau Hlebik Date: Fri, 17 Jul 2020 17:07:23 -0700 Subject: [PATCH 50/87] remediation of S205607 fbshipit-source-id: 5113fe0c527595e4227ff827253b7414abbdf7ac --- .../Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs | 1 + .../Android/Facebook.Yoga.Android/Resources/Resource.designer.cs | 1 + csharp/nuget/_._ | 1 + 3 files changed, 3 insertions(+) diff --git a/csharp/Android/Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs b/csharp/Android/Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs index e69de29b..56de9c5e 100644 --- a/csharp/Android/Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs +++ b/csharp/Android/Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs @@ -0,0 +1 @@ +S205607 diff --git a/csharp/Android/Facebook.Yoga.Android/Resources/Resource.designer.cs b/csharp/Android/Facebook.Yoga.Android/Resources/Resource.designer.cs index e69de29b..56de9c5e 100644 --- a/csharp/Android/Facebook.Yoga.Android/Resources/Resource.designer.cs +++ b/csharp/Android/Facebook.Yoga.Android/Resources/Resource.designer.cs @@ -0,0 +1 @@ +S205607 diff --git a/csharp/nuget/_._ b/csharp/nuget/_._ index e69de29b..56de9c5e 100644 --- a/csharp/nuget/_._ +++ b/csharp/nuget/_._ @@ -0,0 +1 @@ +S205607 From 5ac5624e3fc872bb9e3a899e42f77602539b8fae Mon Sep 17 00:00:00 2001 From: Stanislau Hlebik Date: Fri, 17 Jul 2020 17:07:23 -0700 Subject: [PATCH 51/87] remediation of S205607 fbshipit-source-id: 798decc90db4f13770e97cdce3c0df7d5421b2a3 --- .../Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs | 1 - .../Android/Facebook.Yoga.Android/Resources/Resource.designer.cs | 1 - csharp/nuget/_._ | 1 - 3 files changed, 3 deletions(-) diff --git a/csharp/Android/Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs b/csharp/Android/Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs index 56de9c5e..e69de29b 100644 --- a/csharp/Android/Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs +++ b/csharp/Android/Facebook.Yoga.Android.Tests/Resources/Resource.designer.cs @@ -1 +0,0 @@ -S205607 diff --git a/csharp/Android/Facebook.Yoga.Android/Resources/Resource.designer.cs b/csharp/Android/Facebook.Yoga.Android/Resources/Resource.designer.cs index 56de9c5e..e69de29b 100644 --- a/csharp/Android/Facebook.Yoga.Android/Resources/Resource.designer.cs +++ b/csharp/Android/Facebook.Yoga.Android/Resources/Resource.designer.cs @@ -1 +0,0 @@ -S205607 diff --git a/csharp/nuget/_._ b/csharp/nuget/_._ index 56de9c5e..e69de29b 100644 --- a/csharp/nuget/_._ +++ b/csharp/nuget/_._ @@ -1 +0,0 @@ -S205607 From fc88b2f774f0ab9090d7ca15de6680f26d7285ad Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 20 Jul 2020 00:31:15 -0700 Subject: [PATCH 52/87] Introducing `YGPositionTypeStatic` Summary: Changelog: [Internal] Fabric-specific internal change. This diff introduces a new value for `YGPositionType`: `YGPositionTypeStatic`. No part of Yoga, RN, Litho or CK uses this value yet. `relative` and `static` values behave the same way for now. We also do not change any defaults. So, it should be fine. Reviewed By: SidharthGuglani Differential Revision: D22386732 fbshipit-source-id: 39cd9e818458ac2a91efb175f24a74c8c303ff08 --- gentest/gentest-cs.js | 3 ++- java/com/facebook/yoga/YogaPositionType.java | 10 ++++++---- tests/YGDefaultValuesTest.cpp | 2 +- tests/YGStyleAccessorsTest.cpp | 5 +++-- yoga/YGEnums.cpp | 2 ++ yoga/YGEnums.h | 6 +++++- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/gentest/gentest-cs.js b/gentest/gentest-cs.js index 2e276180..f0cbd7fb 100644 --- a/gentest/gentest-cs.js +++ b/gentest/gentest-cs.js @@ -120,8 +120,9 @@ CSEmitter.prototype = Object.create(Emitter.prototype, { YGOverflowHidden:{value:'YogaOverflow.Hidden'}, YGOverflowVisible:{value:'YogaOverflow.Visible'}, - YGPositionTypeAbsolute:{value:'YogaPositionType.Absolute'}, + YGPositionTypeAbsolute:{value:'YogaPositionType.Static'}, YGPositionTypeRelative:{value:'YogaPositionType.Relative'}, + YGPositionTypeAbsolute:{value:'YogaPositionType.Absolute'}, YGUndefined:{value:'YogaConstants.Undefined'}, diff --git a/java/com/facebook/yoga/YogaPositionType.java b/java/com/facebook/yoga/YogaPositionType.java index 00354f5c..d61c3244 100644 --- a/java/com/facebook/yoga/YogaPositionType.java +++ b/java/com/facebook/yoga/YogaPositionType.java @@ -8,8 +8,9 @@ package com.facebook.yoga; public enum YogaPositionType { - RELATIVE(0), - ABSOLUTE(1); + STATIC(0), + RELATIVE(1), + ABSOLUTE(2); private final int mIntValue; @@ -23,8 +24,9 @@ public enum YogaPositionType { public static YogaPositionType fromInt(int value) { switch (value) { - case 0: return RELATIVE; - case 1: return ABSOLUTE; + case 0: return STATIC; + case 1: return RELATIVE; + case 2: return ABSOLUTE; default: throw new IllegalArgumentException("Unknown enum value: " + value); } } diff --git a/tests/YGDefaultValuesTest.cpp b/tests/YGDefaultValuesTest.cpp index 249a7605..a622c1b3 100644 --- a/tests/YGDefaultValuesTest.cpp +++ b/tests/YGDefaultValuesTest.cpp @@ -20,7 +20,7 @@ TEST(YogaTest, assert_default_values) { ASSERT_EQ(YGAlignFlexStart, YGNodeStyleGetAlignContent(root)); ASSERT_EQ(YGAlignStretch, YGNodeStyleGetAlignItems(root)); ASSERT_EQ(YGAlignAuto, YGNodeStyleGetAlignSelf(root)); - ASSERT_EQ(YGPositionTypeRelative, YGNodeStyleGetPositionType(root)); + ASSERT_EQ(YGPositionTypeStatic, YGNodeStyleGetPositionType(root)); ASSERT_EQ(YGWrapNoWrap, YGNodeStyleGetFlexWrap(root)); ASSERT_EQ(YGOverflowVisible, YGNodeStyleGetOverflow(root)); ASSERT_FLOAT_EQ(0, YGNodeStyleGetFlexGrow(root)); diff --git a/tests/YGStyleAccessorsTest.cpp b/tests/YGStyleAccessorsTest.cpp index 541f354f..d0bda431 100644 --- a/tests/YGStyleAccessorsTest.cpp +++ b/tests/YGStyleAccessorsTest.cpp @@ -132,9 +132,10 @@ ACCESSOR_TEST( ACCESSOR_TEST( positionType, - YGPositionTypeRelative, + YGPositionTypeStatic, YGPositionTypeAbsolute, - YGPositionTypeRelative) + YGPositionTypeRelative, + YGPositionTypeStatic) ACCESSOR_TEST( flexWrap, diff --git a/yoga/YGEnums.cpp b/yoga/YGEnums.cpp index 3c130129..c01d3d94 100644 --- a/yoga/YGEnums.cpp +++ b/yoga/YGEnums.cpp @@ -179,6 +179,8 @@ const char* YGOverflowToString(const YGOverflow value) { const char* YGPositionTypeToString(const YGPositionType value) { switch (value) { + case YGPositionTypeStatic: + return "static"; case YGPositionTypeRelative: return "relative"; case YGPositionTypeAbsolute: diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index 4241281d..3dc458dc 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -128,7 +128,11 @@ YG_ENUM_SEQ_DECL( YGOverflowHidden, YGOverflowScroll) -YG_ENUM_SEQ_DECL(YGPositionType, YGPositionTypeRelative, YGPositionTypeAbsolute) +YG_ENUM_SEQ_DECL( + YGPositionType, + YGPositionTypeStatic, + YGPositionTypeRelative, + YGPositionTypeAbsolute) YG_ENUM_DECL( YGPrintOptions, From 084d5935e6f6bf7306ad8041bdc2f097889b8e58 Mon Sep 17 00:00:00 2001 From: Thomas Nardone Date: Mon, 3 Aug 2020 09:26:28 -0700 Subject: [PATCH 53/87] Tweak stdlib imports in event, utils Summary: Changelog: [Internal][Fixed] - Tweaked stdlib imports Reviewed By: SidharthGuglani Differential Revision: D22860196 fbshipit-source-id: fc0fc1bf05ebbfae7e86bce5e960e58d5944ee5c --- yoga/Utils.cpp | 1 + yoga/event/event.cpp | 1 - yoga/event/event.h | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index c4281b60..edb198d2 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -6,6 +6,7 @@ */ #include "Utils.h" +#include using namespace facebook; diff --git a/yoga/event/event.cpp b/yoga/event/event.cpp index 2b07e381..3af3e83a 100644 --- a/yoga/event/event.cpp +++ b/yoga/event/event.cpp @@ -8,7 +8,6 @@ #include "event.h" #include #include -#include namespace facebook { namespace yoga { diff --git a/yoga/event/event.h b/yoga/event/event.h index 309dacb5..404ec376 100644 --- a/yoga/event/event.h +++ b/yoga/event/event.h @@ -11,6 +11,7 @@ #include #include #include +#include struct YGConfig; struct YGNode; From e1c9d8800e8d4f0edb11010da6270707a166e2ed Mon Sep 17 00:00:00 2001 From: Jiawei Lv Date: Tue, 11 Aug 2020 17:09:47 -0700 Subject: [PATCH 54/87] Assign test_ownership_2020 as owner for unowned java tests in fbandroid Summary: Changelog: [Internal] Reviewed By: IanChilds Differential Revision: D22980855 fbshipit-source-id: d5e394f16eaf0e50367b95b1eec98024b906d3d9 --- java/BUCK | 1 + 1 file changed, 1 insertion(+) diff --git a/java/BUCK b/java/BUCK index a658d7e9..fa0250a3 100644 --- a/java/BUCK +++ b/java/BUCK @@ -110,6 +110,7 @@ yoga_java_library( yoga_java_test( name = "tests", srcs = glob(["tests/**/*.java"]), + contacts = ["oncall+yoga@xmail.facebook.com"], cxx_library_whitelist = CXX_LIBRARY_WHITELIST_FOR_TESTS, use_cxx_libraries = True, visibility = ["PUBLIC"], From e0ae96368c966d1fb5f8ad3de852050c95621a79 Mon Sep 17 00:00:00 2001 From: Paco Estevez Garcia Date: Fri, 28 Aug 2020 06:30:53 -0700 Subject: [PATCH 55/87] Add DoNotStripAny Summary: This diff adds an annotation that also prevents stripping methods, fields and static blocks. This is necessary for D23373168 to be OSS'd Reviewed By: SidharthGuglani Differential Revision: D23395925 fbshipit-source-id: 8456234cb75b15ae87580835e76f8e251ba09a9b --- .../proguard/annotations/DoNotStripAny.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 java/proguard-annotations/src/main/java/com/facebook/proguard/annotations/DoNotStripAny.java diff --git a/java/proguard-annotations/src/main/java/com/facebook/proguard/annotations/DoNotStripAny.java b/java/proguard-annotations/src/main/java/com/facebook/proguard/annotations/DoNotStripAny.java new file mode 100644 index 00000000..48f71f2b --- /dev/null +++ b/java/proguard-annotations/src/main/java/com/facebook/proguard/annotations/DoNotStripAny.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) Facebook, Inc. and its 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.proguard.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.CLASS; + +/** + * Add this annotation to a class to instruct Proguard to not strip it or any of its fields or + * methods out. + * + *

This is useful for methods called via reflection that could appear as unused to Proguard. + */ +@Target({ElementType.TYPE}) +@Retention(CLASS) +public @interface DoNotStripAny {} From f350c7a58e59aea8586f38b5d5e9654ae79da6c6 Mon Sep 17 00:00:00 2001 From: Panagiotis Vekris Date: Thu, 10 Sep 2020 16:00:22 -0700 Subject: [PATCH 56/87] explicitly set types_first=false in flowconfigs Summary: In Flow version 0.134, [types-first](https://flow.org/en/docs/lang/types-first/) will become the default mode for Flow. Given that this mode might introduce some errors due to missing annotations, we're pinning the previously default mode, to avoid introducing new errors. Note that in Jan 2021 we will be removing support for Flow classic mode. * Documentation for properly upgrading to types-first: https://flow.org/en/docs/cli/annotate-exports/ * Announcement post: https://medium.com/flow-type/types-first-a-scalable-new-architecture-for-flow-3d8c7ba1d4eb Reviewed By: mroch Differential Revision: D23606450 fbshipit-source-id: f849275269974e17c0ebe00885e387ccd9956b6d --- javascript/.flowconfig | 1 + website/.flowconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/javascript/.flowconfig b/javascript/.flowconfig index 1fed4453..6a0c16ae 100644 --- a/javascript/.flowconfig +++ b/javascript/.flowconfig @@ -7,5 +7,6 @@ [lints] [options] +types_first=false [strict] diff --git a/website/.flowconfig b/website/.flowconfig index 1fed4453..6a0c16ae 100644 --- a/website/.flowconfig +++ b/website/.flowconfig @@ -7,5 +7,6 @@ [lints] [options] +types_first=false [strict] From 64e245942786227b2f97ccfa5c30ce5c4fd62d79 Mon Sep 17 00:00:00 2001 From: simek Date: Mon, 28 Sep 2020 21:24:45 -0700 Subject: [PATCH 57/87] remove most of tvOS remnants from the code (#29407) Summary: Refs: [0.62 release](https://reactnative.dev/blog/#moving-apple-tv-to-react-native-tvos), https://github.com/facebook/react-native/issues/28706, https://github.com/facebook/react-native/issues/28743, https://github.com/facebook/react-native/issues/29018 This PR removes most of the tvOS remnants in the code. Most of the changes are related to the tvOS platform removal from `.podspec` files, tvOS specific conditionals removal (Obj-C + JS) or tvOS CI/testing pipeline related code. In addition to the changes listed above I have removed the deprecated `Platform.isTVOS` method. I'm not sure how `Platform.isTV` method is correlated with Android TV devices support which is technically not deprecated in the core so I left this method untouched for now. ## Changelog * **[Internal] [Removed]** - remove most of tvOS remnants from the code: * `TVEventHandler`, `TVTouchable`, `RCTTVView`, `RCTTVRemoteHandler` and `RCTTVNavigationEventEmitter` * **[Internal] [Removed]** - remove `TARGET_TV_OS` flag and all the usages * **[iOS] [Removed]** - remove deprecated `Platform.isTVOS` method * **[iOS] [Removed]** - remove deprecated and TV related props from View: * `isTVSelectable`, `hasTVPreferredFocus` and `tvParallaxProperties` * **[iOS] [Removed]** - remove `BackHandler` utility implementation Pull Request resolved: https://github.com/facebook/react-native/pull/29407 Test Plan: Local tests (and iOS CI run) do not yield any errors, but I'm not sure how the CI pipeline would react to those changes. That is the reason why this PR is being posted as Draft. Some tweaks and code adjustment could be required. Reviewed By: PeteTheHeat Differential Revision: D22619441 Pulled By: shergin fbshipit-source-id: 9aaf3840c5e8bd469c2cfcfa7c5b441ef71b30b6 --- ReactYoga.xcodeproj/project.pbxproj | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ReactYoga.xcodeproj/project.pbxproj b/ReactYoga.xcodeproj/project.pbxproj index 715c686a..090c6e09 100644 --- a/ReactYoga.xcodeproj/project.pbxproj +++ b/ReactYoga.xcodeproj/project.pbxproj @@ -191,7 +191,6 @@ 27595AD71E575C7800CCE2B1 /* SampleCxxModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D41E03699D0018521A /* SampleCxxModule.h */; }; 27595AD81E575C7800CCE2B1 /* SystraceSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D92B0D51E03699D0018521A /* SystraceSection.h */; }; 2D0EB9F32021067800CAF88A /* RCTUIUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = F1EFDA4E201F660F00EE6E4C /* RCTUIUtils.m */; }; - 2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */; }; 2D1D83CE1F74E2DA00615550 /* libdouble-conversion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D383D621EBD27B9005632C8 /* libdouble-conversion.a */; }; 2D3B5E931D9B087300451313 /* RCTErrorInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCA8A41D3591E700450C31 /* RCTErrorInfo.m */; }; 2D3B5E941D9B087900451313 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */; }; @@ -269,8 +268,6 @@ 3D0B842A1EC0B49400B2BD8E /* RCTTVRemoteHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0B84281EC0B49400B2BD8E /* RCTTVRemoteHandler.h */; }; 3D0B842B1EC0B49400B2BD8E /* RCTTVRemoteHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D0B84291EC0B49400B2BD8E /* RCTTVRemoteHandler.m */; }; 3D0B842C1EC0B4EA00B2BD8E /* RCTTVView.m in Sources */ = {isa = PBXBuildFile; fileRef = 130443D71E401AD800D93A67 /* RCTTVView.m */; }; - 3D0B842F1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */; }; - 3D0B84301EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D0B842E1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.m */; }; 3D0E378A1F1CC40000DCAC9F /* RCTWebSocketModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0E37891F1CC40000DCAC9F /* RCTWebSocketModule.h */; }; 3D0E378E1F1CC59100DCAC9F /* RCTWebSocketModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D0E37891F1CC40000DCAC9F /* RCTWebSocketModule.h */; }; 3D0E378F1F1CC5CF00DCAC9F /* RCTWebSocketModule.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 3D0E37891F1CC40000DCAC9F /* RCTWebSocketModule.h */; }; @@ -1275,7 +1272,6 @@ 594F0A471FD233BD007FBE96 /* RCTSurfaceView.h in Copy Headers */, 594F0A481FD233BD007FBE96 /* RCTSurfaceHostingView.h in Copy Headers */, 594F0A491FD233BD007FBE96 /* RCTSurfaceSizeMeasureMode.h in Copy Headers */, - 2D16E68E1FA4FD3900B85C8A /* RCTTVNavigationEventEmitter.h in Copy Headers */, 59500D481F71C67600B122B7 /* RCTUIManagerUtils.h in Copy Headers */, 3D0E37901F1CC5E100DCAC9F /* RCTWebSocketModule.h in Copy Headers */, 5960C1BF1F0804F50066FD5B /* RCTLayoutAnimation.h in Copy Headers */, @@ -1876,8 +1872,6 @@ 39C50FFA2046EE3500CEE534 /* RCTVersion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTVersion.m; sourceTree = ""; }; 3D0B84281EC0B49400B2BD8E /* RCTTVRemoteHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTVRemoteHandler.h; sourceTree = ""; }; 3D0B84291EC0B49400B2BD8E /* RCTTVRemoteHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTVRemoteHandler.m; sourceTree = ""; }; - 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTVNavigationEventEmitter.h; sourceTree = ""; }; - 3D0B842E1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTVNavigationEventEmitter.m; sourceTree = ""; }; 3D0E37891F1CC40000DCAC9F /* RCTWebSocketModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTWebSocketModule.h; path = WebSocket/RCTWebSocketModule.h; sourceTree = ""; }; 3D1E68D81CABD13900DD7465 /* RCTDisplayLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDisplayLink.h; sourceTree = ""; }; 3D1E68D91CABD13900DD7465 /* RCTDisplayLink.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDisplayLink.m; sourceTree = ""; }; @@ -2346,8 +2340,6 @@ 0EEEA8DE2239002200A8C82D /* RCTSurfacePresenterStub.m */, 13B07FED1A69327A00A75B9A /* RCTTiming.h */, 13B07FEE1A69327A00A75B9A /* RCTTiming.m */, - 3D0B842D1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h */, - 3D0B842E1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.m */, 13E067481A70F434002CDEE1 /* RCTUIManager.h */, 13E067491A70F434002CDEE1 /* RCTUIManager.m */, 59EB6DB91EBD6FC90072A5E7 /* RCTUIManagerObserverCoordinator.h */, @@ -2945,7 +2937,6 @@ 3D302F311DF828F800D6DDAE /* RCTBundleURLProvider.h in Headers */, 3D302F321DF828F800D6DDAE /* RCTConvert.h in Headers */, 3D302F331DF828F800D6DDAE /* RCTDefines.h in Headers */, - 3D0B842F1EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.h in Headers */, 3D302F341DF828F800D6DDAE /* RCTDisplayLink.h in Headers */, 3D302F351DF828F800D6DDAE /* RCTErrorCustomizer.h in Headers */, 3D302F361DF828F800D6DDAE /* RCTErrorInfo.h in Headers */, @@ -3994,7 +3985,6 @@ 2D3B5EC81D9B095800451313 /* RCTActivityIndicatorViewManager.m in Sources */, 3DCD185D1DF978E7007FE5A1 /* RCTReloadCommand.m in Sources */, 130443DB1E401ADD00D93A67 /* RCTConvert+Transform.m in Sources */, - 3D0B84301EC0B51200B2BD8E /* RCTTVNavigationEventEmitter.m in Sources */, 2D3B5EC61D9B095000451313 /* RCTProfileTrampoline-x86_64.S in Sources */, 2D3B5EA61D9B08CA00451313 /* RCTTouchEvent.m in Sources */, 2D8C2E331DA40441000EE098 /* RCTMultipartStreamReader.m in Sources */, From 07eac0c6e21bf0ddbe5e87bd18a8940cff83a0b8 Mon Sep 17 00:00:00 2001 From: Pasquale Anatriello Date: Thu, 29 Oct 2020 09:23:02 -0700 Subject: [PATCH 58/87] Fix clone issue in YogaNodeJNIBase Summary: Changelog: Fix the cloneWithChildren implementation that was not copying the list of children on the java object. We were missing on copying the list of children when cloning. This is pretty bad as it means that the clone operation was mutating the old node as well as the new. When multiple threads were involved this could cause crashes. Reviewed By: SidharthGuglani Differential Revision: D24565307 fbshipit-source-id: 4e2e111db389e25c315ce7603b4018ac695bb0f1 --- java/com/facebook/yoga/YogaNodeJNIBase.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/com/facebook/yoga/YogaNodeJNIBase.java b/java/com/facebook/yoga/YogaNodeJNIBase.java index 406e75e5..7ab391cc 100644 --- a/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -116,6 +116,9 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { public YogaNodeJNIBase cloneWithChildren() { try { YogaNodeJNIBase clonedYogaNode = (YogaNodeJNIBase) super.clone(); + if (clonedYogaNode.mChildren != null) { + clonedYogaNode.mChildren = new ArrayList<>(clonedYogaNode.mChildren); + } long clonedNativePointer = YogaNative.jni_YGNodeCloneJNI(mNativePointer); clonedYogaNode.mOwner = null; clonedYogaNode.mNativePointer = clonedNativePointer; From e65b1ef6548d2ecfdf3d1cec230581be606a927e Mon Sep 17 00:00:00 2001 From: Kris Georges Date: Tue, 10 Nov 2020 08:21:19 -0800 Subject: [PATCH 59/87] Fix Yoga Playground website Litho codegen bugs Summary: Yoga Playground website changing direction results in no change to Litho code because of this typo Reviewed By: SidharthGuglani Differential Revision: D24818769 fbshipit-source-id: 1633513d4a25aead2008b59d52f669293214c598 --- website/src/components/Playground/src/CodeLitho.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/components/Playground/src/CodeLitho.js b/website/src/components/Playground/src/CodeLitho.js index 66e89a3e..cc96c840 100644 --- a/website/src/components/Playground/src/CodeLitho.js +++ b/website/src/components/Playground/src/CodeLitho.js @@ -24,7 +24,7 @@ function getEnum(yogaEnum: string, value: string | number): string { position: 'Position', flexWrap: 'Wrap', positionType: 'PositionType', - direction: 'Driection', + direction: 'Direction', }; if (!enumLookup[yogaEnum]) { From b043669972ee59bc3e7906e3707816ec3eccda1e Mon Sep 17 00:00:00 2001 From: Ron Edelstein Date: Thu, 17 Dec 2020 19:33:39 -0800 Subject: [PATCH 60/87] Explicitly set autoglob (long tail) Reviewed By: fbanurag, strulovich Differential Revision: D25620908 fbshipit-source-id: 1dd737d451ddfd07baa427902bdf1c96d7e67e64 --- android/sample/java/com/facebook/samples/yoga/BUCK | 1 + android/src/main/java/com/facebook/yoga/android/BUCK | 1 + 2 files changed, 2 insertions(+) diff --git a/android/sample/java/com/facebook/samples/yoga/BUCK b/android/sample/java/com/facebook/samples/yoga/BUCK index 31609016..502c19f3 100644 --- a/android/sample/java/com/facebook/samples/yoga/BUCK +++ b/android/sample/java/com/facebook/samples/yoga/BUCK @@ -8,6 +8,7 @@ load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID_JAVA_TARGET", "ANDROID_SAM yoga_android_library( name = "yoga", srcs = glob(["**/*.java"]), + autoglob = False, visibility = [ "PUBLIC", ], diff --git a/android/src/main/java/com/facebook/yoga/android/BUCK b/android/src/main/java/com/facebook/yoga/android/BUCK index c760ba0b..20408c78 100644 --- a/android/src/main/java/com/facebook/yoga/android/BUCK +++ b/android/src/main/java/com/facebook/yoga/android/BUCK @@ -8,6 +8,7 @@ load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID_RES_TARGET", "INFER_ANNOTA yoga_android_library( name = "android", srcs = glob(["**/*.java"]), + autoglob = False, visibility = [ "PUBLIC", ], From a38ec3d7a493c5497016d4d1b4e05b89cf5d6f65 Mon Sep 17 00:00:00 2001 From: Panagiotis Vekris Date: Mon, 4 Jan 2021 21:05:07 -0800 Subject: [PATCH 61/87] pin "classic" roots to v0.140 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: In Flow v0.143 types-first will become the only supported mode in Flow. As such the `types_first` configuration option will become invalid. To prevent breaking roots that have `types_first=false` set and are **unversioned**, this diff pins their version to v0.140, which is the last released version in fbsource. ## Repro First compute the list of all `.flowconfig`s: ``` zbgf '.flowconfig$' | grep -v '^fbsource/fbcode/flow' | grep -v 'Binary file' | awk -F':' '{ print $1 }' | sort -u > all-flowconfigs.txt ``` Compute `.flowconfig`s that don’t have a version: ``` zbgs -f '\.flowconfig' '[version]' | grep -v '^fbsource/fbcode/flow' | grep -v 'Binary file' | awk -F':' '{ print $1 }' | sort -u > versioned-flowconfigs.txt comm -23 all-flowconfigs.txt versioned-flowconfigs.txt > unversioned-flowconfigs.txt ``` Compute `.flowconfig`s that have `types_first=false`: ``` zbgr -f '\.flowconfig' '^types_first=false$' | grep -v '^fbsource/fbcode/flow' | grep -v 'Binary file' | awk -F':' '{ print $1 }' | sort -u > types_first-false-flowconfigs.txt ``` **and** no pinned version: ``` comm -12 unversioned-flowconfigs.txt types_first-false-flowconfigs.txt | grep 'fbsource' > pin-version-flowconfigs.txt ``` Update the `.flowconfig`s: ``` cat ~/scratch/flowconfigs/pin-version-flowconfigs-fbsource.txt | xargs -I{} bash -c 'printf "\n[version]\n^0.140.0\n" >> {}' ``` Reviewed By: mroch Differential Revision: D25771452 fbshipit-source-id: 876d6310e4e1aafb81d3ef3051f4e9e9e838a633 --- javascript/.flowconfig | 3 +++ website/.flowconfig | 3 +++ 2 files changed, 6 insertions(+) diff --git a/javascript/.flowconfig b/javascript/.flowconfig index 6a0c16ae..6bd402f8 100644 --- a/javascript/.flowconfig +++ b/javascript/.flowconfig @@ -10,3 +10,6 @@ types_first=false [strict] + +[version] +^0.140.0 diff --git a/website/.flowconfig b/website/.flowconfig index 6a0c16ae..6bd402f8 100644 --- a/website/.flowconfig +++ b/website/.flowconfig @@ -10,3 +10,6 @@ types_first=false [strict] + +[version] +^0.140.0 From 584dfe961e6220d684bfd847facb4e7b2717a712 Mon Sep 17 00:00:00 2001 From: Andres Suarez Date: Sun, 10 Jan 2021 10:03:53 -0800 Subject: [PATCH 62/87] Apply clang-format update fixes Reviewed By: igorsugak Differential Revision: D25861849 fbshipit-source-id: 840dc1061e557717c7f9ffcccbc09c24b96b78e0 --- .../YogaKitSample/ViewController.m | 18 +++++++------ javascript/sources/Node.cc | 4 +-- tests/EventsTest.cpp | 4 +-- tests/YGComputedMarginTest.cpp | 26 ++++++++++--------- tests/YGComputedPaddingTest.cpp | 26 ++++++++++--------- tests/YGTreeMutationTest.cpp | 21 ++++++++------- yoga/CompactValue.h | 4 +-- yoga/Yoga.cpp | 4 +-- 8 files changed, 57 insertions(+), 50 deletions(-) diff --git a/YogaKit/YogaKitSample/YogaKitSample/ViewController.m b/YogaKit/YogaKitSample/YogaKitSample/ViewController.m index 145fa47b..dedf03d2 100644 --- a/YogaKit/YogaKitSample/YogaKitSample/ViewController.m +++ b/YogaKit/YogaKitSample/YogaKitSample/ViewController.m @@ -28,17 +28,19 @@ UIView* child2 = [UIView new]; child2.backgroundColor = [UIColor greenColor]; - child2.frame = (CGRect){.size = { - .width = 200, - .height = 100, - }}; + child2.frame = (CGRect){ + .size = { + .width = 200, + .height = 100, + }}; UIView* child3 = [UIView new]; child3.backgroundColor = [UIColor yellowColor]; - child3.frame = (CGRect){.size = { - .width = 100, - .height = 100, - }}; + child3.frame = (CGRect){ + .size = { + .width = 100, + .height = 100, + }}; [child2 addSubview:child3]; [root addSubview:child1]; diff --git a/javascript/sources/Node.cc b/javascript/sources/Node.cc index 7e6833fe..421cfa71 100644 --- a/javascript/sources/Node.cc +++ b/javascript/sources/Node.cc @@ -23,8 +23,8 @@ static YGSize globalMeasureFunc( Node const& node = *reinterpret_cast(YGNodeGetContext(nodeRef)); Size size = node.callMeasureFunc(width, widthMode, height, heightMode); - YGSize ygSize = {static_cast(size.width), - static_cast(size.height)}; + YGSize ygSize = { + static_cast(size.width), static_cast(size.height)}; return ygSize; } diff --git a/tests/EventsTest.cpp b/tests/EventsTest.cpp index cf887b2d..e8300846 100644 --- a/tests/EventsTest.cpp +++ b/tests/EventsTest.cpp @@ -303,8 +303,8 @@ EventArgs createArgs( }; EventArgs args = createArgs(node, data); - args.eventTestDataPtr = {new EventTestData{eventTestData}, - deleteEventTestData}; + args.eventTestDataPtr = { + new EventTestData{eventTestData}, deleteEventTestData}; return args; } diff --git a/tests/YGComputedMarginTest.cpp b/tests/YGComputedMarginTest.cpp index b74e4174..fedfd561 100644 --- a/tests/YGComputedMarginTest.cpp +++ b/tests/YGComputedMarginTest.cpp @@ -29,12 +29,13 @@ TEST(YogaTest, computed_layout_margin) { } TEST(YogaTest, margin_side_overrides_horizontal_and_vertical) { - const std::array edges = {{YGEdgeTop, - YGEdgeBottom, - YGEdgeStart, - YGEdgeEnd, - YGEdgeLeft, - YGEdgeRight}}; + const std::array edges = { + {YGEdgeTop, + YGEdgeBottom, + YGEdgeStart, + YGEdgeEnd, + YGEdgeLeft, + YGEdgeRight}}; for (float edgeValue = 0; edgeValue < 2; ++edgeValue) { for (const auto& edge : edges) { @@ -58,12 +59,13 @@ TEST(YogaTest, margin_side_overrides_horizontal_and_vertical) { } TEST(YogaTest, margin_side_overrides_all) { - const std::array edges = {{YGEdgeTop, - YGEdgeBottom, - YGEdgeStart, - YGEdgeEnd, - YGEdgeLeft, - YGEdgeRight}}; + const std::array edges = { + {YGEdgeTop, + YGEdgeBottom, + YGEdgeStart, + YGEdgeEnd, + YGEdgeLeft, + YGEdgeRight}}; for (float edgeValue = 0; edgeValue < 2; ++edgeValue) { for (const auto& edge : edges) { diff --git a/tests/YGComputedPaddingTest.cpp b/tests/YGComputedPaddingTest.cpp index 677ed3a6..c3aabab7 100644 --- a/tests/YGComputedPaddingTest.cpp +++ b/tests/YGComputedPaddingTest.cpp @@ -29,12 +29,13 @@ TEST(YogaTest, computed_layout_padding) { } TEST(YogaTest, padding_side_overrides_horizontal_and_vertical) { - const std::array edges = {{YGEdgeTop, - YGEdgeBottom, - YGEdgeStart, - YGEdgeEnd, - YGEdgeLeft, - YGEdgeRight}}; + const std::array edges = { + {YGEdgeTop, + YGEdgeBottom, + YGEdgeStart, + YGEdgeEnd, + YGEdgeLeft, + YGEdgeRight}}; for (float edgeValue = 0; edgeValue < 2; ++edgeValue) { for (const auto& edge : edges) { @@ -58,12 +59,13 @@ TEST(YogaTest, padding_side_overrides_horizontal_and_vertical) { } TEST(YogaTest, padding_side_overrides_all) { - const std::array edges = {{YGEdgeTop, - YGEdgeBottom, - YGEdgeStart, - YGEdgeEnd, - YGEdgeLeft, - YGEdgeRight}}; + const std::array edges = { + {YGEdgeTop, + YGEdgeBottom, + YGEdgeStart, + YGEdgeEnd, + YGEdgeLeft, + YGEdgeRight}}; for (float edgeValue = 0; edgeValue < 2; ++edgeValue) { for (const auto& edge : edges) { diff --git a/tests/YGTreeMutationTest.cpp b/tests/YGTreeMutationTest.cpp index bf07f39e..26f0b900 100644 --- a/tests/YGTreeMutationTest.cpp +++ b/tests/YGTreeMutationTest.cpp @@ -29,8 +29,8 @@ TEST(YogaTest, set_children_adds_children_to_parent) { const std::vector expectedChildren = {root_child0, root_child1}; ASSERT_EQ(children, expectedChildren); - const std::vector owners = {YGNodeGetOwner(root_child0), - YGNodeGetOwner(root_child1)}; + const std::vector owners = { + YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; const std::vector expectedOwners = {root, root}; ASSERT_EQ(owners, expectedOwners); @@ -49,8 +49,8 @@ TEST(YogaTest, set_children_to_empty_removes_old_children) { const std::vector expectedChildren = {}; ASSERT_EQ(children, expectedChildren); - const std::vector owners = {YGNodeGetOwner(root_child0), - YGNodeGetOwner(root_child1)}; + const std::vector owners = { + YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; const std::vector expectedOwners = {nullptr, nullptr}; ASSERT_EQ(owners, expectedOwners); @@ -73,8 +73,8 @@ TEST(YogaTest, set_children_replaces_non_common_children) { const std::vector expectedChildren = {root_child2, root_child3}; ASSERT_EQ(children, expectedChildren); - const std::vector owners = {YGNodeGetOwner(root_child0), - YGNodeGetOwner(root_child1)}; + const std::vector owners = { + YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; const std::vector expectedOwners = {nullptr, nullptr}; ASSERT_EQ(owners, expectedOwners); @@ -100,10 +100,11 @@ TEST(YogaTest, set_children_keeps_and_reorders_common_children) { root_child2, root_child1, root_child3}; ASSERT_EQ(children, expectedChildren); - const std::vector owners = {YGNodeGetOwner(root_child0), - YGNodeGetOwner(root_child1), - YGNodeGetOwner(root_child2), - YGNodeGetOwner(root_child3)}; + const std::vector owners = { + YGNodeGetOwner(root_child0), + YGNodeGetOwner(root_child1), + YGNodeGetOwner(root_child2), + YGNodeGetOwner(root_child3)}; const std::vector expectedOwners = {nullptr, root, root, root}; ASSERT_EQ(owners, expectedOwners); diff --git a/yoga/CompactValue.h b/yoga/CompactValue.h index be933a16..f398668e 100644 --- a/yoga/CompactValue.h +++ b/yoga/CompactValue.h @@ -125,8 +125,8 @@ public: data.repr &= ~PERCENT_BIT; data.repr += BIAS; - return YGValue{data.value, - payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint}; + return YGValue{ + data.value, payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint}; } bool isUndefined() const noexcept { diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 97e64075..2db6be21 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -3531,8 +3531,8 @@ static void YGNodelayoutImpl( YGNodeBoundAxisWithinMinAndMax( node, crossAxis, - YGFloatOptional{totalLineCrossDim + - paddingAndBorderAxisCross}, + YGFloatOptional{ + totalLineCrossDim + paddingAndBorderAxisCross}, crossAxisownerSize) .unwrap()), paddingAndBorderAxisCross), From 2cb46cf3e2c9d47662dafe370e8c67e5838cd5e5 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Fri, 5 Feb 2021 03:39:55 -0800 Subject: [PATCH 63/87] instance of checks for YogaNodeJniBase Summary: Changelog: [Internal][Yoga] - Added instance of checks in `YogaNodeJNIBase` class to prevent `ClassCastException`s. This was happening for some NT android tests - Mocked Yoga Node object was being passed in the `addChildAt` api Stack Trace of exception java.lang.ClassCastException: com.facebook.yoga.YogaNode$MockitoMock$1408896622 cannot be cast to com.facebook.yoga.YogaNodeJNIBase at com.facebook.yoga.YogaNodeJNIBase.addChildAt(YogaNodeJNIBase.java:86) at com.facebook.litho.DefaultInternalNode.addChildAt(DefaultInternalNode.java:220) at com.facebook.litho.DefaultInternalNode.child(DefaultInternalNode.java:377) at com.facebook.litho.DefaultInternalNode.child(DefaultInternalNode.java:360) at com.facebook.litho.Column.resolve(Column.java:118) at com.facebook.litho.Layout.create(Layout.java:172) Reviewed By: Andrey-Mishanin Differential Revision: D26114992 fbshipit-source-id: 774a689609e67f9244b81c6788b62cd61cd96d14 --- java/com/facebook/yoga/YogaNodeJNIBase.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/java/com/facebook/yoga/YogaNodeJNIBase.java b/java/com/facebook/yoga/YogaNodeJNIBase.java index 7ab391cc..6b3dcd26 100644 --- a/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -83,6 +83,9 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { } public void addChildAt(YogaNode c, int i) { + if (!(c instanceof YogaNodeJNIBase)) { + return; + } YogaNodeJNIBase child = (YogaNodeJNIBase) c; if (child.mOwner != null) { throw new IllegalStateException("Child already has a parent, it must be removed first."); @@ -105,6 +108,9 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { } public void swapChildAt(YogaNode newChild, int position) { + if (!(newChild instanceof YogaNodeJNIBase)) { + return; + } YogaNodeJNIBase child = (YogaNodeJNIBase) newChild; mChildren.remove(position); mChildren.add(position, child); @@ -223,6 +229,9 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { @Override public void copyStyle(YogaNode srcNode) { + if (!(srcNode instanceof YogaNodeJNIBase)) { + return; + } YogaNative.jni_YGNodeCopyStyleJNI(mNativePointer, ((YogaNodeJNIBase) srcNode).mNativePointer); } From 651c527e946826b36e1466981adbe08701ceb7a6 Mon Sep 17 00:00:00 2001 From: Ruslan Serebriakov Date: Thu, 11 Feb 2021 10:37:41 -0800 Subject: [PATCH 64/87] CKDimension Summary: [rsrbk@devvm3461.lla0 /data/users/rsrbk/fbsource/fbobjc] fastmod --accept-all CKRelativeDimension RCRelativeDimension [rsrbk@devvm3461.lla0 /data/users/rsrbk/fbsource/fbobjc] fastmod --accept-all CKRelativeSize RCRelativeSize [rsrbk@devvm3461.lla0 /data/users/rsrbk/fbsource/fbobjc] fastmod --accept-all ComponentKit/RCDimension.h RenderCore/RCDimension.h Reviewed By: kfirapps Differential Revision: D26228615 fbshipit-source-id: 9c06128b324e1c6ece6fc21fbab1c041e5f5825a --- website/src/components/Playground/src/CodeComponentKit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/components/Playground/src/CodeComponentKit.js b/website/src/components/Playground/src/CodeComponentKit.js index 74cc2db2..00111508 100644 --- a/website/src/components/Playground/src/CodeComponentKit.js +++ b/website/src/components/Playground/src/CodeComponentKit.js @@ -73,9 +73,9 @@ function keyLookup(key: string): string { function getValue(value) { if (typeof value === 'string' && /%$/.test(value)) { - return `CKRelativeDimension::Percent(${parseFloat(value)})`; + return `RCRelativeDimension::Percent(${parseFloat(value)})`; } else if (value === 'auto') { - return 'CKRelativeDimension::Auto()'; + return 'RCRelativeDimension::Auto()'; } else { return String(parseFloat(value)); } From de36e85004dce6ef0f2cee9208bfee9036db7e04 Mon Sep 17 00:00:00 2001 From: Aditya Sharat Date: Tue, 16 Feb 2021 10:17:36 -0800 Subject: [PATCH 65/87] Adds InternalNode#freeze() API Summary: Litho needs a new API which is called immediately before yoga begins layout calculations so that the InternalNode gets the opportunity to finalise itself; i.e. perform the last mutations and in effect avoid any more mutations to the hierarchy. See D26373731 where the mutations from `Layout#collectResults` is moved back into the InternalNode. Changelog: [Internal] Adds new API to YogaNodeJNIBase Reviewed By: SidharthGuglani Differential Revision: D26373730 fbshipit-source-id: 471346d3444986ada91e86c95f5f9fb98bcd2fa6 --- java/com/facebook/yoga/YogaNode.java | 18 ++++++++++++------ java/com/facebook/yoga/YogaNodeJNIBase.java | 14 +++++++++++++- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/java/com/facebook/yoga/YogaNode.java b/java/com/facebook/yoga/YogaNode.java index 9fc8bac9..dfec8ec5 100644 --- a/java/com/facebook/yoga/YogaNode.java +++ b/java/com/facebook/yoga/YogaNode.java @@ -10,6 +10,14 @@ package com.facebook.yoga; import javax.annotation.Nullable; public abstract class YogaNode { + + /** The interface the {@link #getData()} object can optionally implement. */ + public interface Inputs { + + /** Requests the data object to disable mutations of its inputs. */ + void freeze(); + } + public abstract void reset(); public abstract int getChildCount(); @@ -25,12 +33,10 @@ public abstract class YogaNode { public abstract YogaNode removeChildAt(int i); /** - * @returns the {@link YogaNode} that owns this {@link YogaNode}. - * The owner is used to identify the YogaTree that a {@link YogaNode} belongs - * to. - * This method will return the parent of the {@link YogaNode} when the - * {@link YogaNode} only belongs to one YogaTree or null when the - * {@link YogaNode} is shared between two or more YogaTrees. + * @returns the {@link YogaNode} that owns this {@link YogaNode}. The owner is used to identify + * the YogaTree that a {@link YogaNode} belongs to. This method will return the parent of the + * {@link YogaNode} when the {@link YogaNode} only belongs to one YogaTree or null when the + * {@link YogaNode} is shared between two or more YogaTrees. */ @Nullable public abstract YogaNode getOwner(); diff --git a/java/com/facebook/yoga/YogaNodeJNIBase.java b/java/com/facebook/yoga/YogaNodeJNIBase.java index 6b3dcd26..03354556 100644 --- a/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -197,12 +197,17 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { long[] nativePointers = null; YogaNodeJNIBase[] nodes = null; + freeze(); + ArrayList n = new ArrayList<>(); n.add(this); for (int i = 0; i < n.size(); ++i) { List children = n.get(i).mChildren; if (children != null) { - n.addAll(children); + for (YogaNodeJNIBase child : children) { + child.freeze(); + n.add(child); + } } } @@ -215,6 +220,13 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { YogaNative.jni_YGNodeCalculateLayoutJNI(mNativePointer, width, height, nativePointers, nodes); } + private void freeze() { + Object data = getData(); + if (data instanceof Inputs) { + ((Inputs) data).freeze(); + } + } + public void dirty() { YogaNative.jni_YGNodeMarkDirtyJNI(mNativePointer); } From 36e70c9ca0ef4817d8f05caf0f8f49709ab24141 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Thu, 25 Feb 2021 06:34:24 -0800 Subject: [PATCH 66/87] Fix Yoga test Summary: Changelog: [Internal][Yoga] Fixed unit test for default yoga style property Reviewed By: pasqualeanatriello Differential Revision: D26664040 fbshipit-source-id: 9c0af4e846ead3d90c75753e836570ccac760178 --- java/tests/com/facebook/yoga/YogaNodeStylePropertiesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/tests/com/facebook/yoga/YogaNodeStylePropertiesTest.java b/java/tests/com/facebook/yoga/YogaNodeStylePropertiesTest.java index 649c7279..c39ea024 100644 --- a/java/tests/com/facebook/yoga/YogaNodeStylePropertiesTest.java +++ b/java/tests/com/facebook/yoga/YogaNodeStylePropertiesTest.java @@ -191,7 +191,7 @@ public class YogaNodeStylePropertiesTest { public void testPositionTypeDefault() { final YogaNode node = createNode(); - assertEquals(YogaPositionType.RELATIVE, node.getPositionType()); + assertEquals(YogaPositionType.STATIC, node.getPositionType()); } @Test From 0429704d5ec4f565056005d899dabd47089bf961 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Thu, 25 Feb 2021 06:34:24 -0800 Subject: [PATCH 67/87] version bump Reviewed By: pasqualeanatriello Differential Revision: D26664041 fbshipit-source-id: 5a4d0d176074c8831dd18681993463fe25e2642f --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 820eae63..4dc8a8e6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.jvmargs=-Xmx1536M -VERSION_NAME=1.16.0-SNAPSHOT +VERSION_NAME=1.17.0 POM_URL=https://github.com/facebook/yoga POM_SCM_URL=https://github.com/facebook/yoga.git POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git From c1a28f3f54bfed299199b4a8916818891a7be055 Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Thu, 25 Feb 2021 06:34:24 -0800 Subject: [PATCH 68/87] Add back snapshot in version for next release Summary: Changelog: [Internal][Yoga] version bump Reviewed By: pasqualeanatriello Differential Revision: D26664063 fbshipit-source-id: ceb8d31a99f85db7d1fde20bd77584a537d356c6 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 4dc8a8e6..382f62fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.jvmargs=-Xmx1536M -VERSION_NAME=1.17.0 +VERSION_NAME=1.17.0-SNAPSHOT POM_URL=https://github.com/facebook/yoga POM_SCM_URL=https://github.com/facebook/yoga.git POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git From ccdea0f31bc71d9297b767ba567f7c1f2e2ee30a Mon Sep 17 00:00:00 2001 From: Stiopa Koltsov Date: Mon, 1 Mar 2021 13:13:44 -0800 Subject: [PATCH 69/87] xplat: switch random files to Starlark Summary: We need to get rid of all `# BUILD FILE SYNTAX: PYTHON_DSL` to disable hybrid parser after we make Starlark default everywhere. This is first bunch of changes. Reviewed By: mzlee Differential Revision: D26727784 fbshipit-source-id: 05c5f4d039feb4ce06169ac6d2fc5c49711125cd --- java/BUCK | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/BUCK b/java/BUCK index fa0250a3..627c5678 100644 --- a/java/BUCK +++ b/java/BUCK @@ -1,5 +1,3 @@ -# BUILD FILE SYNTAX: PYTHON_DSL - # Copyright (c) Facebook, Inc. and its affiliates. # # This source code is licensed under the MIT license found in the From 1745c23a122cf04013e18631802670421415be21 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Wed, 10 Mar 2021 12:36:47 -0800 Subject: [PATCH 70/87] Fix various C++ warnings (#31002) Summary: Fix warnings about implicit type truncation. ## Changelog [Internal] [Fixed] - Fix various C++ warnings Pull Request resolved: https://github.com/facebook/react-native/pull/31002 Test Plan: Almost all the changes here are simply making explicit conversions which are already occurring. With the exception of a couple of constants being changed from doubles to floats. With these changes I am able to remove a bunch of warning suppressions in react-native-windows. Reviewed By: shergin Differential Revision: D26900502 Pulled By: rozele fbshipit-source-id: d5e415282815c2212a840a863713287bbf118c10 --- yoga/BitUtils.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/yoga/BitUtils.h b/yoga/BitUtils.h index 1c32e9ec..2161effc 100644 --- a/yoga/BitUtils.h +++ b/yoga/BitUtils.h @@ -45,8 +45,9 @@ void setEnumData(uint32_t& flags, size_t index, int newValue) { template void setEnumData(uint8_t& flags, size_t index, int newValue) { - flags = (flags & ~mask(bitWidthFn(), index)) | - ((newValue << index) & (mask(bitWidthFn(), index))); + flags = (flags & ~static_cast(mask(bitWidthFn(), index))) | + ((newValue << index) & + (static_cast(mask(bitWidthFn(), index)))); } constexpr bool getBooleanData(int flags, size_t index) { From 342aebe1d73e5770a1862b6a94c6b877c1439a9b Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Wed, 10 Mar 2021 13:08:48 -0800 Subject: [PATCH 71/87] Fixes layout of nodes with YGDisplayNone and YGPositionTypeAbsolute (#1068) Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1068 There is an issue in react-native when the Yoga node position type is set to absolute and display: none is set where the node layout calculation gives the absolute dimensions, rather than the expected 0 x 0. Here are some OSS issues tracking this: https://github.com/facebook/react-native/issues/18415 https://github.com/microsoft/react-native-windows/issues/7289 ## Changelog [General] [Fix] - Fixes layout of nodes with YGDisplayNone and YGPositionTypeAbsolute Reviewed By: Andrey-Mishanin Differential Revision: D26849307 fbshipit-source-id: 197618aa3c4e1b3b7efeba7ea4efd30b2d1c982d --- csharp/tests/Facebook.Yoga/YGDisplayTest.cs | 49 ++++++++++++++++-- gentest/fixtures/YGDisplayTest.html | 4 ++ gentest/gentest.js | 6 +-- gentest/gentest.rb | 15 +++--- .../com/facebook/yoga/YGDisplayTest.java | 48 ++++++++++++++++-- .../tests/Facebook.Yoga/YGDisplayTest.js | 50 ++++++++++++++++++- tests/YGDisplayTest.cpp | 47 ++++++++++++++++- yoga/Yoga.cpp | 3 +- 8 files changed, 201 insertions(+), 21 deletions(-) diff --git a/csharp/tests/Facebook.Yoga/YGDisplayTest.cs b/csharp/tests/Facebook.Yoga/YGDisplayTest.cs index 237686ba..659cb37f 100644 --- a/csharp/tests/Facebook.Yoga/YGDisplayTest.cs +++ b/csharp/tests/Facebook.Yoga/YGDisplayTest.cs @@ -1,9 +1,10 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ + // @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html using System; @@ -333,5 +334,47 @@ namespace Facebook.Yoga Assert.AreEqual(0f, root_child1.LayoutHeight); } + [Test] + public void Test_display_none_with_position_absolute() + { + YogaConfig config = new YogaConfig(); + + YogaNode root = new YogaNode(config); + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(config); + root_child0.PositionType = YogaPositionType.Absolute; + root_child0.Width = 100; + root_child0.Height = 100; + root_child0.Display = YogaDisplay.None; + root.Insert(0, root_child0); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(0f, root_child0.LayoutWidth); + Assert.AreEqual(0f, root_child0.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(0f, root_child0.LayoutWidth); + Assert.AreEqual(0f, root_child0.LayoutHeight); + } + } } diff --git a/gentest/fixtures/YGDisplayTest.html b/gentest/fixtures/YGDisplayTest.html index 74d11ba4..f11533f8 100644 --- a/gentest/fixtures/YGDisplayTest.html +++ b/gentest/fixtures/YGDisplayTest.html @@ -25,3 +25,7 @@

+ +
+
+
diff --git a/gentest/gentest.js b/gentest/gentest.js index ca370928..12e76f33 100755 --- a/gentest/gentest.js +++ b/gentest/gentest.js @@ -41,11 +41,11 @@ function assert(condition, message) { function printTest(e, LTRContainer, RTLContainer, genericContainer) { e.push([ - '/**', + '/*', ' * Copyright (c) Facebook, Inc. and its affiliates.', ' *', - ' * This source code is licensed under the MIT license found in the LICENSE', - ' * file in the root directory of this source tree.', + ' * This source code is licensed under the MIT license found in the', + ' * LICENSE file in the root directory of this source tree.', ' */', '// @Generated by gentest/gentest.rb from gentest/fixtures/' + document.title + '.html', '', diff --git a/gentest/gentest.rb b/gentest/gentest.rb index 22114501..01fec93e 100644 --- a/gentest/gentest.rb +++ b/gentest/gentest.rb @@ -7,13 +7,14 @@ require 'watir' require 'fileutils' -caps = Selenium::WebDriver::Remote::Capabilities.chrome( - "loggingPrefs"=>{ - "browser"=>"ALL", - "performance"=>"ALL" - } -) -browser = Watir::Browser.new(:chrome, :desired_capabilities => caps, :switches => ['--force-device-scale-factor=1', '--window-position=0,0']) +browser = Watir::Browser.new(:chrome, "goog:loggingPrefs" => { + "browser" => "ALL", + "performance" => "ALL" + }, + "chromeOptions" => { + "w3c" => "false" + }, + :switches => ['--force-device-scale-factor=1', '--window-position=0,0']) Dir.chdir(File.dirname($0)) diff --git a/java/tests/com/facebook/yoga/YGDisplayTest.java b/java/tests/com/facebook/yoga/YGDisplayTest.java index f1e6f896..999548bd 100644 --- a/java/tests/com/facebook/yoga/YGDisplayTest.java +++ b/java/tests/com/facebook/yoga/YGDisplayTest.java @@ -1,9 +1,10 @@ -/** +/* * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ + // @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html package com.facebook.yoga; @@ -337,6 +338,47 @@ public class YGDisplayTest { assertEquals(0f, root_child1.getLayoutHeight(), 0.0f); } + @Test + public void test_display_none_with_position_absolute() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = createNode(config); + root_child0.setPositionType(YogaPositionType.ABSOLUTE); + root_child0.setWidth(100f); + root_child0.setHeight(100f); + root_child0.setDisplay(YogaDisplay.NONE); + root.addChildAt(root_child0, 0); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(0f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child0.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(0f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child0.getLayoutHeight(), 0.0f); + } + private YogaNode createNode(YogaConfig config) { return mNodeFactory.create(config); } diff --git a/javascript/tests/Facebook.Yoga/YGDisplayTest.js b/javascript/tests/Facebook.Yoga/YGDisplayTest.js index e5be4a55..cf65ab22 100644 --- a/javascript/tests/Facebook.Yoga/YGDisplayTest.js +++ b/javascript/tests/Facebook.Yoga/YGDisplayTest.js @@ -1,9 +1,10 @@ /** * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ + // @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html var Yoga = Yoga || require("../../sources/entry-" + process.env.TEST_ENTRY); @@ -342,3 +343,48 @@ it("display_none_with_position", function () { config.free(); } }); +it("display_none_with_position_absolute", function () { + var config = Yoga.Config.create(); + + try { + var root = Yoga.Node.create(config); + root.setWidth(100); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(config); + root_child0.setPositionType(Yoga.POSITION_TYPE_ABSOLUTE); + root_child0.setWidth(100); + root_child0.setHeight(100); + root_child0.setDisplay(Yoga.DISPLAY_NONE); + root.insertChild(root_child0, 0); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + } finally { + if (typeof root !== "undefined") { + root.freeRecursive(); + } + + config.free(); + } +}); diff --git a/tests/YGDisplayTest.cpp b/tests/YGDisplayTest.cpp index ebd2bcd5..edc53358 100644 --- a/tests/YGDisplayTest.cpp +++ b/tests/YGDisplayTest.cpp @@ -1,9 +1,10 @@ /* * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ + // @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html #include @@ -327,3 +328,45 @@ TEST(YogaTest, display_none_with_position) { YGConfigFree(config); } + +TEST(YogaTest, display_none_with_position_absolute) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeStyleSetDisplay(root_child0, YGDisplayNone); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 2db6be21..f24563df 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -3557,7 +3557,8 @@ static void YGNodelayoutImpl( if (performLayout) { // STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN for (auto child : node->getChildren()) { - if (child->getStyle().positionType() != YGPositionTypeAbsolute) { + if (child->getStyle().display() == YGDisplayNone || + child->getStyle().positionType() != YGPositionTypeAbsolute) { continue; } YGNodeAbsoluteLayoutChild( From 41384fab7b64824d9e7dd15ba042ee86ad5dc1b6 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Mon, 15 Mar 2021 16:53:05 -0700 Subject: [PATCH 72/87] Optimize edge value resolution Summary: Noticed in simpleperf this was a very hot method, showing 8ms spent in these methods in our sample application. By splitting the method out in a horizontal and vertical variant we can simplify cases enormously and check for begin/end in one go. Changelog: [Internal] Reviewed By: SidharthGuglani Differential Revision: D27010008 fbshipit-source-id: 22fed58c7476e1d716b0191b55997c7a06e63223 --- yoga/YGNode.cpp | 221 ++++++++++++++++++++++--------------------- yoga/YGNode.h | 11 +++ yoga/YGNodePrint.cpp | 11 ++- yoga/Yoga-internal.h | 5 - yoga/Yoga.cpp | 30 ------ 5 files changed, 129 insertions(+), 149 deletions(-) diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 1ee1bde6..f4c14bf3 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -50,89 +50,111 @@ void YGNode::print(void* printContext) { } } +CompactValue YGNode::computeEdgeValueForRow( + const YGStyle::Edges& edges, + YGEdge rowEdge, + YGEdge edge, + CompactValue defaultValue) { + if (!edges[rowEdge].isUndefined()) { + return edges[rowEdge]; + } else if (!edges[edge].isUndefined()) { + return edges[edge]; + } else if (!edges[YGEdgeHorizontal].isUndefined()) { + return edges[YGEdgeHorizontal]; + } else if (!edges[YGEdgeAll].isUndefined()) { + return edges[YGEdgeAll]; + } else { + return defaultValue; + } +} + +CompactValue YGNode::computeEdgeValueForColumn( + const YGStyle::Edges& edges, + YGEdge edge, + CompactValue defaultValue) { + if (!edges[edge].isUndefined()) { + return edges[edge]; + } else if (!edges[YGEdgeVertical].isUndefined()) { + return edges[YGEdgeVertical]; + } else if (!edges[YGEdgeAll].isUndefined()) { + return edges[YGEdgeAll]; + } else { + return defaultValue; + } +} + YGFloatOptional YGNode::getLeadingPosition( const YGFlexDirection axis, const float axisSize) const { - if (YGFlexDirectionIsRow(axis)) { - auto leadingPosition = YGComputedEdgeValue( - style_.position(), YGEdgeStart, CompactValue::ofUndefined()); - if (!leadingPosition.isUndefined()) { - return YGResolveValue(leadingPosition, axisSize); - } - } - - auto leadingPosition = YGComputedEdgeValue( - style_.position(), leading[axis], CompactValue::ofUndefined()); - - return leadingPosition.isUndefined() - ? YGFloatOptional{0} - : YGResolveValue(leadingPosition, axisSize); + auto leadingPosition = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.position(), + YGEdgeStart, + leading[axis], + CompactValue::ofZero()) + : computeEdgeValueForColumn( + style_.position(), leading[axis], CompactValue::ofZero()); + return YGResolveValue(leadingPosition, axisSize); } YGFloatOptional YGNode::getTrailingPosition( const YGFlexDirection axis, const float axisSize) const { - if (YGFlexDirectionIsRow(axis)) { - auto trailingPosition = YGComputedEdgeValue( - style_.position(), YGEdgeEnd, CompactValue::ofUndefined()); - if (!trailingPosition.isUndefined()) { - return YGResolveValue(trailingPosition, axisSize); - } - } - - auto trailingPosition = YGComputedEdgeValue( - style_.position(), trailing[axis], CompactValue::ofUndefined()); - - return trailingPosition.isUndefined() - ? YGFloatOptional{0} - : YGResolveValue(trailingPosition, axisSize); + auto trailingPosition = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.position(), + YGEdgeEnd, + trailing[axis], + CompactValue::ofZero()) + : computeEdgeValueForColumn( + style_.position(), trailing[axis], CompactValue::ofZero()); + return YGResolveValue(trailingPosition, axisSize); } bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const { - return (YGFlexDirectionIsRow(axis) && - !YGComputedEdgeValue( - style_.position(), YGEdgeStart, CompactValue::ofUndefined()) - .isUndefined()) || - !YGComputedEdgeValue( - style_.position(), leading[axis], CompactValue::ofUndefined()) - .isUndefined(); + auto leadingPosition = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.position(), + YGEdgeStart, + leading[axis], + CompactValue::ofUndefined()) + : computeEdgeValueForColumn( + style_.position(), leading[axis], CompactValue::ofUndefined()); + return !leadingPosition.isUndefined(); } bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const { - return (YGFlexDirectionIsRow(axis) && - !YGComputedEdgeValue( - style_.position(), YGEdgeEnd, CompactValue::ofUndefined()) - .isUndefined()) || - !YGComputedEdgeValue( - style_.position(), trailing[axis], CompactValue::ofUndefined()) - .isUndefined(); + auto trailingPosition = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.position(), + YGEdgeEnd, + trailing[axis], + CompactValue::ofUndefined()) + : computeEdgeValueForColumn( + style_.position(), trailing[axis], CompactValue::ofUndefined()); + return !trailingPosition.isUndefined(); } YGFloatOptional YGNode::getLeadingMargin( const YGFlexDirection axis, const float widthSize) const { - if (YGFlexDirectionIsRow(axis) && - !style_.margin()[YGEdgeStart].isUndefined()) { - return YGResolveValueMargin(style_.margin()[YGEdgeStart], widthSize); - } - - return YGResolveValueMargin( - YGComputedEdgeValue( - style_.margin(), leading[axis], CompactValue::ofZero()), - widthSize); + auto leadingMargin = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.margin(), YGEdgeStart, leading[axis], CompactValue::ofZero()) + : computeEdgeValueForColumn( + style_.margin(), leading[axis], CompactValue::ofZero()); + return YGResolveValueMargin(leadingMargin, widthSize); } YGFloatOptional YGNode::getTrailingMargin( const YGFlexDirection axis, const float widthSize) const { - if (YGFlexDirectionIsRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) { - return YGResolveValueMargin(style_.margin()[YGEdgeEnd], widthSize); - } - - return YGResolveValueMargin( - YGComputedEdgeValue( - style_.margin(), trailing[axis], CompactValue::ofZero()), - widthSize); + auto trailingMargin = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.margin(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) + : computeEdgeValueForColumn( + style_.margin(), trailing[axis], CompactValue::ofZero()); + return YGResolveValueMargin(trailingMargin, widthSize); } YGFloatOptional YGNode::getMarginForAxis( @@ -147,7 +169,6 @@ YGSize YGNode::measure( float height, YGMeasureMode heightMode, void* layoutContext) { - return facebook::yoga::detail::getBooleanData(flags, measureUsesContext_) ? measure_.withContext( this, width, widthMode, height, heightMode, layoutContext) @@ -448,68 +469,48 @@ bool YGNode::isNodeFlexible() { } float YGNode::getLeadingBorder(const YGFlexDirection axis) const { - YGValue leadingBorder; - if (YGFlexDirectionIsRow(axis) && - !style_.border()[YGEdgeStart].isUndefined()) { - leadingBorder = style_.border()[YGEdgeStart]; - if (leadingBorder.value >= 0) { - return leadingBorder.value; - } - } - - leadingBorder = YGComputedEdgeValue( - style_.border(), leading[axis], CompactValue::ofZero()); - return YGFloatMax(leadingBorder.value, 0.0f); + YGValue leadingBorder = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.border(), YGEdgeStart, leading[axis], CompactValue::ofZero()) + : computeEdgeValueForColumn( + style_.border(), leading[axis], CompactValue::ofZero()); + return fmaxf(leadingBorder.value, 0.0f); } -float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const { - YGValue trailingBorder; - if (YGFlexDirectionIsRow(flexDirection) && - !style_.border()[YGEdgeEnd].isUndefined()) { - trailingBorder = style_.border()[YGEdgeEnd]; - if (trailingBorder.value >= 0.0f) { - return trailingBorder.value; - } - } - - trailingBorder = YGComputedEdgeValue( - style_.border(), trailing[flexDirection], CompactValue::ofZero()); - return YGFloatMax(trailingBorder.value, 0.0f); +float YGNode::getTrailingBorder(const YGFlexDirection axis) const { + YGValue trailingBorder = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.border(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) + : computeEdgeValueForColumn( + style_.border(), trailing[axis], CompactValue::ofZero()); + return fmaxf(trailingBorder.value, 0.0f); } YGFloatOptional YGNode::getLeadingPadding( const YGFlexDirection axis, const float widthSize) const { - const YGFloatOptional paddingEdgeStart = - YGResolveValue(style_.padding()[YGEdgeStart], widthSize); - if (YGFlexDirectionIsRow(axis) && - !style_.padding()[YGEdgeStart].isUndefined() && - !paddingEdgeStart.isUndefined() && paddingEdgeStart.unwrap() >= 0.0f) { - return paddingEdgeStart; - } - - YGFloatOptional resolvedValue = YGResolveValue( - YGComputedEdgeValue( - style_.padding(), leading[axis], CompactValue::ofZero()), - widthSize); - return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); + auto leadingPadding = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.padding(), + YGEdgeStart, + leading[axis], + CompactValue::ofZero()) + : computeEdgeValueForColumn( + style_.padding(), leading[axis], CompactValue::ofZero()); + return YGFloatOptionalMax( + YGResolveValue(leadingPadding, widthSize), YGFloatOptional(0.0f)); } YGFloatOptional YGNode::getTrailingPadding( const YGFlexDirection axis, const float widthSize) const { - const YGFloatOptional paddingEdgeEnd = - YGResolveValue(style_.padding()[YGEdgeEnd], widthSize); - if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) { - return paddingEdgeEnd; - } - - YGFloatOptional resolvedValue = YGResolveValue( - YGComputedEdgeValue( - style_.padding(), trailing[axis], CompactValue::ofZero()), - widthSize); - - return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); + auto trailingPadding = YGFlexDirectionIsRow(axis) + ? computeEdgeValueForRow( + style_.padding(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) + : computeEdgeValueForColumn( + style_.padding(), trailing[axis], CompactValue::ofZero()); + return YGFloatOptionalMax( + YGResolveValue(trailingPadding, widthSize), YGFloatOptional(0.0f)); } YGFloatOptional YGNode::getLeadingPaddingAndBorder( diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 63d98fe3..4b6e6277 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -193,6 +193,17 @@ public: return resolvedDimensions_[index]; } + static CompactValue computeEdgeValueForColumn( + const YGStyle::Edges& edges, + YGEdge edge, + CompactValue defaultValue); + + static CompactValue computeEdgeValueForRow( + const YGStyle::Edges& edges, + YGEdge rowEdge, + YGEdge edge, + CompactValue defaultValue); + // Methods related to positions, margin, padding and border YGFloatOptional getLeadingPosition( const YGFlexDirection axis, diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp index 26efa485..72d147db 100644 --- a/yoga/YGNodePrint.cpp +++ b/yoga/YGNodePrint.cpp @@ -104,10 +104,13 @@ static void appendEdgeIfNotUndefined( const string& str, const YGStyle::Edges& edges, const YGEdge edge) { - appendNumberIfNotUndefined( - base, - str, - YGComputedEdgeValue(edges, edge, detail::CompactValue::ofUndefined())); + // TODO: this doesn't take RTL / YGEdgeStart / YGEdgeEnd into account + auto value = (edge == YGEdgeLeft || edge == YGEdgeRight) + ? YGNode::computeEdgeValueForRow( + edges, edge, edge, detail::CompactValue::ofUndefined()) + : YGNode::computeEdgeValueForColumn( + edges, edge, detail::CompactValue::ofUndefined()); + appendNumberIfNotUndefined(base, str, value); } void YGNodeToString( diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 1a22f24c..b671f177 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -144,8 +144,3 @@ static const float kDefaultFlexShrink = 0.0f; static const float kWebDefaultFlexShrink = 1.0f; extern bool YGFloatsEqual(const float a, const float b); -extern facebook::yoga::detail::CompactValue YGComputedEdgeValue( - const facebook::yoga::detail::Values< - facebook::yoga::enums::count()>& edges, - YGEdge edge, - facebook::yoga::detail::CompactValue defaultValue); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index f24563df..196fc7b7 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -110,36 +110,6 @@ YOGA_EXPORT bool YGFloatIsUndefined(const float value) { return facebook::yoga::isUndefined(value); } -detail::CompactValue YGComputedEdgeValue( - const YGStyle::Edges& edges, - YGEdge edge, - detail::CompactValue defaultValue) { - if (!edges[edge].isUndefined()) { - return edges[edge]; - } - - if ((edge == YGEdgeTop || edge == YGEdgeBottom) && - !edges[YGEdgeVertical].isUndefined()) { - return edges[YGEdgeVertical]; - } - - if ((edge == YGEdgeLeft || edge == YGEdgeRight || edge == YGEdgeStart || - edge == YGEdgeEnd) && - !edges[YGEdgeHorizontal].isUndefined()) { - return edges[YGEdgeHorizontal]; - } - - if (!edges[YGEdgeAll].isUndefined()) { - return edges[YGEdgeAll]; - } - - if (edge == YGEdgeStart || edge == YGEdgeEnd) { - return detail::CompactValue::ofUndefined(); - } - - return defaultValue; -} - YOGA_EXPORT void* YGNodeGetContext(YGNodeRef node) { return node->getContext(); } From e87f429703677061129a39ef6dc5f19da33608e1 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Mon, 15 Mar 2021 16:53:05 -0700 Subject: [PATCH 73/87] Simplify YGNodeCalculateAvailableInnerDim Summary: Avoid recalculating margin and padding by pre-subtracting the margin from `availableWidth` and inlining the calculation of `paddingAndBorderAxisCross`. Changelog: [Internal] Reviewed By: SidharthGuglani Differential Revision: D27010094 fbshipit-source-id: afc3cf251a0306b9e5d7f0dc6856feee8d1dca6e --- yoga/Yoga.cpp | 80 +++++++++++++++++++++++++++------------------------ yoga/Yoga.h | 2 +- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 196fc7b7..db3a0704 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1848,21 +1848,11 @@ static void YGZeroOutLayoutRecursivly( static float YGNodeCalculateAvailableInnerDim( const YGNodeConstRef node, - YGFlexDirection axis, - float availableDim, - float ownerDim, - float ownerDimForMarginPadding) { - YGFlexDirection direction = - YGFlexDirectionIsRow(axis) ? YGFlexDirectionRow : YGFlexDirectionColumn; - YGDimension dimension = - YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight; - - const float margin = - node->getMarginForAxis(direction, ownerDimForMarginPadding).unwrap(); - const float paddingAndBorder = - YGNodePaddingAndBorderForAxis(node, direction, ownerDimForMarginPadding); - - float availableInnerDim = availableDim - margin - paddingAndBorder; + const YGDimension dimension, + const float availableDim, + const float paddingAndBorder, + const float ownerDim) { + float availableInnerDim = availableDim - paddingAndBorder; // Max dimension overrides predefined dimension value; Min dimension in turn // overrides both of the above if (!YGFloatIsUndefined(availableInnerDim)) { @@ -2836,12 +2826,14 @@ static void YGNodelayoutImpl( const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; const float crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth; - const float leadingPaddingAndBorderCross = - node->getLeadingPaddingAndBorder(crossAxis, ownerWidth).unwrap(); const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth); + const float leadingPaddingAndBorderCross = + node->getLeadingPaddingAndBorder(crossAxis, ownerWidth).unwrap(); + const float trailingPaddingAndBorderCross = + node->getTrailingPaddingAndBorder(crossAxis, ownerWidth).unwrap(); const float paddingAndBorderAxisCross = - YGNodePaddingAndBorderForAxis(node, crossAxis, ownerWidth); + leadingPaddingAndBorderCross + trailingPaddingAndBorderCross; YGMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; @@ -2858,30 +2850,20 @@ static void YGNodelayoutImpl( const float marginAxisColumn = node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); - const auto& minDimensions = node->getStyle().minDimensions(); - const auto& maxDimensions = node->getStyle().maxDimensions(); - const float minInnerWidth = - YGResolveValue(minDimensions[YGDimensionWidth], ownerWidth).unwrap() - - paddingAndBorderAxisRow; - const float maxInnerWidth = - YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap() - - paddingAndBorderAxisRow; - const float minInnerHeight = - YGResolveValue(minDimensions[YGDimensionHeight], ownerHeight).unwrap() - - paddingAndBorderAxisColumn; - const float maxInnerHeight = - YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight).unwrap() - - paddingAndBorderAxisColumn; - - const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; - const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight; - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS float availableInnerWidth = YGNodeCalculateAvailableInnerDim( - node, YGFlexDirectionRow, availableWidth, ownerWidth, ownerWidth); + node, + YGDimensionWidth, + availableWidth - marginAxisRow, + paddingAndBorderAxisRow, + ownerWidth); float availableInnerHeight = YGNodeCalculateAvailableInnerDim( - node, YGFlexDirectionColumn, availableHeight, ownerHeight, ownerWidth); + node, + YGDimensionHeight, + availableHeight - marginAxisColumn, + paddingAndBorderAxisColumn, + ownerHeight); float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; @@ -2953,6 +2935,28 @@ static void YGNodelayoutImpl( // If we don't measure with exact main dimension we want to ensure we don't // violate min and max if (measureModeMainDim != YGMeasureModeExactly) { + const auto& minDimensions = node->getStyle().minDimensions(); + const auto& maxDimensions = node->getStyle().maxDimensions(); + const float minInnerWidth = + YGResolveValue(minDimensions[YGDimensionWidth], ownerWidth).unwrap() - + paddingAndBorderAxisRow; + const float maxInnerWidth = + YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap() - + paddingAndBorderAxisRow; + const float minInnerHeight = + YGResolveValue(minDimensions[YGDimensionHeight], ownerHeight) + .unwrap() - + paddingAndBorderAxisColumn; + const float maxInnerHeight = + YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight) + .unwrap() - + paddingAndBorderAxisColumn; + + const float minInnerMainDim = + isMainAxisRow ? minInnerWidth : minInnerHeight; + const float maxInnerMainDim = + isMainAxisRow ? maxInnerWidth : maxInnerHeight; + if (!YGFloatIsUndefined(minInnerMainDim) && collectedFlexItemsValues.sizeConsumedOnCurrentLine < minInnerMainDim) { diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 87901a28..86cd65e2 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -107,7 +107,7 @@ WIN_EXPORT void YGNodeMarkDirty(YGNodeRef node); // Marks the current node and all its descendants as dirty. // -// Intended to be used for Uoga benchmarks. Don't use in production, as calling +// Intended to be used for Yoga benchmarks. Don't use in production, as calling // `YGCalculateLayout` will cause the recalculation of each and every node. WIN_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(YGNodeRef node); From b2095801ba3c5621e33ba7cbd7aae0c0371f40b3 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Mon, 15 Mar 2021 16:53:05 -0700 Subject: [PATCH 74/87] Simplify YGNodeEmptyContainer / YGNodeWithMeasureFunc / YGNodeFixedSize Summary: These methods are only ever called just after setting the various YGStyle props. Therefore we can read any padding / margin / border state from there rather than recalculating it. Changelog: [Internal] Reviewed By: SidharthGuglani Differential Revision: D27010098 fbshipit-source-id: a33f879b25c54cfdb0ffc724b6aa325858e97df5 --- yoga/Yoga.cpp | 124 +++++++++++++++++++++----------------------------- 1 file changed, 52 insertions(+), 72 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index db3a0704..9553366e 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1651,40 +1651,33 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( availableHeight = YGUndefined; } - const float paddingAndBorderAxisRow = - YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); - const float paddingAndBorderAxisColumn = - YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth); - const float marginAxisRow = - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); - const float marginAxisColumn = - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); + const auto& padding = node->getLayout().padding; + const auto& border = node->getLayout().border; + const float paddingAndBorderAxisRow = padding[YGEdgeLeft] + + padding[YGEdgeRight] + border[YGEdgeLeft] + border[YGEdgeRight]; + const float paddingAndBorderAxisColumn = padding[YGEdgeTop] + + padding[YGEdgeBottom] + border[YGEdgeTop] + border[YGEdgeBottom]; // We want to make sure we don't call measure with negative size const float innerWidth = YGFloatIsUndefined(availableWidth) ? availableWidth - : YGFloatMax(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow); + : YGFloatMax(0, availableWidth - paddingAndBorderAxisRow); const float innerHeight = YGFloatIsUndefined(availableHeight) ? availableHeight - : YGFloatMax( - 0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn); + : YGFloatMax(0, availableHeight - paddingAndBorderAxisColumn); if (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly) { // Don't bother sizing the text if both dimensions are already defined. node->setLayoutMeasuredDimension( YGNodeBoundAxis( - node, - YGFlexDirectionRow, - availableWidth - marginAxisRow, - ownerWidth, - ownerWidth), + node, YGFlexDirectionRow, availableWidth, ownerWidth, ownerWidth), YGDimensionWidth); node->setLayoutMeasuredDimension( YGNodeBoundAxis( node, YGFlexDirectionColumn, - availableHeight - marginAxisColumn, + availableHeight, ownerHeight, ownerWidth), YGDimensionHeight); @@ -1721,7 +1714,7 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( (widthMeasureMode == YGMeasureModeUndefined || widthMeasureMode == YGMeasureModeAtMost) ? measuredSize.width + paddingAndBorderAxisRow - : availableWidth - marginAxisRow, + : availableWidth, ownerWidth, ownerWidth), YGDimensionWidth); @@ -1733,7 +1726,7 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( (heightMeasureMode == YGMeasureModeUndefined || heightMeasureMode == YGMeasureModeAtMost) ? measuredSize.height + paddingAndBorderAxisColumn - : availableHeight - marginAxisColumn, + : availableHeight, ownerHeight, ownerWidth), YGDimensionHeight); @@ -1750,37 +1743,28 @@ static void YGNodeEmptyContainerSetMeasuredDimensions( const YGMeasureMode heightMeasureMode, const float ownerWidth, const float ownerHeight) { - const float paddingAndBorderAxisRow = - YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); - const float paddingAndBorderAxisColumn = - YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth); - const float marginAxisRow = - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); - const float marginAxisColumn = - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); + const auto& padding = node->getLayout().padding; + const auto& border = node->getLayout().border; + float width = availableWidth; + if (widthMeasureMode == YGMeasureModeUndefined || + widthMeasureMode == YGMeasureModeAtMost) { + width = padding[YGEdgeLeft] + padding[YGEdgeRight] + border[YGEdgeLeft] + + border[YGEdgeRight]; + } node->setLayoutMeasuredDimension( - YGNodeBoundAxis( - node, - YGFlexDirectionRow, - (widthMeasureMode == YGMeasureModeUndefined || - widthMeasureMode == YGMeasureModeAtMost) - ? paddingAndBorderAxisRow - : availableWidth - marginAxisRow, - ownerWidth, - ownerWidth), + YGNodeBoundAxis(node, YGFlexDirectionRow, width, ownerWidth, ownerWidth), YGDimensionWidth); + float height = availableHeight; + if (heightMeasureMode == YGMeasureModeUndefined || + heightMeasureMode == YGMeasureModeAtMost) { + height = padding[YGEdgeTop] + padding[YGEdgeBottom] + border[YGEdgeTop] + + border[YGEdgeBottom]; + } node->setLayoutMeasuredDimension( YGNodeBoundAxis( - node, - YGFlexDirectionColumn, - (heightMeasureMode == YGMeasureModeUndefined || - heightMeasureMode == YGMeasureModeAtMost) - ? paddingAndBorderAxisColumn - : availableHeight - marginAxisColumn, - ownerHeight, - ownerWidth), + node, YGFlexDirectionColumn, height, ownerHeight, ownerWidth), YGDimensionHeight); } @@ -1798,11 +1782,6 @@ static bool YGNodeFixedSizeSetMeasuredDimensions( heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) || (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly)) { - auto marginAxisColumn = - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); - auto marginAxisRow = - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); - node->setLayoutMeasuredDimension( YGNodeBoundAxis( node, @@ -1811,7 +1790,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions( (widthMeasureMode == YGMeasureModeAtMost && availableWidth < 0.0f) ? 0.0f - : availableWidth - marginAxisRow, + : availableWidth, ownerWidth, ownerWidth), YGDimensionWidth); @@ -1824,7 +1803,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions( (heightMeasureMode == YGMeasureModeAtMost && availableHeight < 0.0f) ? 0.0f - : availableHeight - marginAxisColumn, + : availableHeight, ownerHeight, ownerWidth), YGDimensionHeight); @@ -2739,16 +2718,22 @@ static void YGNodelayoutImpl( const YGEdge startEdge = direction == YGDirectionLTR ? YGEdgeLeft : YGEdgeRight; const YGEdge endEdge = direction == YGDirectionLTR ? YGEdgeRight : YGEdgeLeft; - node->setLayoutMargin( - node->getLeadingMargin(flexRowDirection, ownerWidth).unwrap(), startEdge); - node->setLayoutMargin( - node->getTrailingMargin(flexRowDirection, ownerWidth).unwrap(), endEdge); - node->setLayoutMargin( - node->getLeadingMargin(flexColumnDirection, ownerWidth).unwrap(), - YGEdgeTop); - node->setLayoutMargin( - node->getTrailingMargin(flexColumnDirection, ownerWidth).unwrap(), - YGEdgeBottom); + + const float marginRowLeading = + node->getLeadingMargin(flexRowDirection, ownerWidth).unwrap(); + node->setLayoutMargin(marginRowLeading, startEdge); + const float marginRowTrailing = + node->getTrailingMargin(flexRowDirection, ownerWidth).unwrap(); + node->setLayoutMargin(marginRowTrailing, endEdge); + const float marginColumnLeading = + node->getLeadingMargin(flexColumnDirection, ownerWidth).unwrap(); + node->setLayoutMargin(marginColumnLeading, YGEdgeTop); + const float marginColumnTrailing = + node->getTrailingMargin(flexColumnDirection, ownerWidth).unwrap(); + node->setLayoutMargin(marginColumnTrailing, YGEdgeBottom); + + const float marginAxisRow = marginRowLeading + marginRowTrailing; + const float marginAxisColumn = marginColumnLeading + marginColumnTrailing; node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), startEdge); node->setLayoutBorder(node->getTrailingBorder(flexRowDirection), endEdge); @@ -2771,8 +2756,8 @@ static void YGNodelayoutImpl( if (node->hasMeasureFunc()) { YGNodeWithMeasureFuncSetMeasuredDimensions( node, - availableWidth, - availableHeight, + availableWidth - marginAxisRow, + availableHeight - marginAxisColumn, widthMeasureMode, heightMeasureMode, ownerWidth, @@ -2787,8 +2772,8 @@ static void YGNodelayoutImpl( if (childCount == 0) { YGNodeEmptyContainerSetMeasuredDimensions( node, - availableWidth, - availableHeight, + availableWidth - marginAxisRow, + availableHeight - marginAxisColumn, widthMeasureMode, heightMeasureMode, ownerWidth, @@ -2801,8 +2786,8 @@ static void YGNodelayoutImpl( if (!performLayout && YGNodeFixedSizeSetMeasuredDimensions( node, - availableWidth, - availableHeight, + availableWidth - marginAxisRow, + availableHeight - marginAxisColumn, widthMeasureMode, heightMeasureMode, ownerWidth, @@ -2845,11 +2830,6 @@ static void YGNodelayoutImpl( const float paddingAndBorderAxisColumn = isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain; - const float marginAxisRow = - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); - const float marginAxisColumn = - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS float availableInnerWidth = YGNodeCalculateAvailableInnerDim( From 67b6c24d7bd1bac5869f95832ff1cf8b43d4a617 Mon Sep 17 00:00:00 2001 From: Altaibayar Tseveenbayar Date: Thu, 18 Mar 2021 03:42:31 -0700 Subject: [PATCH 75/87] Yoga Visual Studio project file fix Summary: Yoga Visual Studio project file was outdated. Made it back working/compilable Reviewed By: Andrey-Mishanin Differential Revision: D27138942 fbshipit-source-id: 5d57e61dbb415db54e255e148739c2e670f3bd23 --- csharp/Yoga/Yoga.vcxproj | 7 +- csharp/Yoga/Yoga.vcxproj.filters | 221 +++++++++++++++++-------------- 2 files changed, 124 insertions(+), 104 deletions(-) diff --git a/csharp/Yoga/Yoga.vcxproj b/csharp/Yoga/Yoga.vcxproj index 5899a0db..0bb66327 100755 --- a/csharp/Yoga/Yoga.vcxproj +++ b/csharp/Yoga/Yoga.vcxproj @@ -227,6 +227,8 @@ + + @@ -236,6 +238,7 @@ + @@ -243,14 +246,16 @@ + + - + diff --git a/csharp/Yoga/Yoga.vcxproj.filters b/csharp/Yoga/Yoga.vcxproj.filters index 3243c630..c03f853a 100755 --- a/csharp/Yoga/Yoga.vcxproj.filters +++ b/csharp/Yoga/Yoga.vcxproj.filters @@ -1,104 +1,119 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Resource Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + \ No newline at end of file From db6be5286ebc7e4a824797178c6205613852cd5f Mon Sep 17 00:00:00 2001 From: Altaibayar Tseveenbayar Date: Fri, 19 Mar 2021 19:22:49 -0700 Subject: [PATCH 76/87] C4244 possible precision loss warning fix Summary: Fixing `warning C4244: 'argument': conversion from 'double' to 'float', possible loss of data` Changelog: [Internal] Reviewed By: SidharthGuglani Differential Revision: D27132355 fbshipit-source-id: 55ff35be368ef4f6093865eb88c17e753250d179 --- yoga/Utils.cpp | 2 +- yoga/Yoga-internal.h | 4 ++++ yoga/Yoga.cpp | 28 ++++++++++++++++------------ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp index edb198d2..eaa74b06 100644 --- a/yoga/Utils.cpp +++ b/yoga/Utils.cpp @@ -55,7 +55,7 @@ bool YGFloatsEqual(const float a, const float b) { bool YGDoubleEqual(const double a, const double b) { if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fabs(a - b) < 0.0001f; + return fabs(a - b) < 0.0001; } return yoga::isUndefined(a) && yoga::isUndefined(b); } diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index b671f177..acd173be 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -33,6 +33,10 @@ inline bool isUndefined(float value) { return std::isnan(value); } +inline bool isUndefined(double value) { + return std::isnan(value); +} + } // namespace yoga } // namespace facebook diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 9553366e..33f70e82 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -106,6 +106,10 @@ static int YGDefaultLog( #undef YG_UNUSED #endif +static inline bool YGDoubleIsUndefined(const double value) { + return facebook::yoga::isUndefined(value); +} + YOGA_EXPORT bool YGFloatIsUndefined(const float value) { return facebook::yoga::isUndefined(value); } @@ -3620,10 +3624,10 @@ YOGA_EXPORT float YGRoundValueToPixelGrid( const double pointScaleFactor, const bool forceCeil, const bool forceFloor) { - double scaledValue = ((double) value) * pointScaleFactor; + double scaledValue = value * pointScaleFactor; // We want to calculate `fractial` such that `floor(scaledValue) = scaledValue // - fractial`. - double fractial = fmod(scaledValue, 1.0f); + double fractial = fmod(scaledValue, 1.0); if (fractial < 0) { // This branch is for handling negative numbers for `value`. // @@ -3645,25 +3649,25 @@ YOGA_EXPORT float YGRoundValueToPixelGrid( if (YGDoubleEqual(fractial, 0)) { // First we check if the value is already rounded scaledValue = scaledValue - fractial; - } else if (YGDoubleEqual(fractial, 1.0f)) { - scaledValue = scaledValue - fractial + 1.0f; + } else if (YGDoubleEqual(fractial, 1.0)) { + scaledValue = scaledValue - fractial + 1.0; } else if (forceCeil) { // Next we check if we need to use forced rounding - scaledValue = scaledValue - fractial + 1.0f; + scaledValue = scaledValue - fractial + 1.0; } else if (forceFloor) { scaledValue = scaledValue - fractial; } else { // Finally we just round the value scaledValue = scaledValue - fractial + - (!YGFloatIsUndefined(fractial) && - (fractial > 0.5f || YGDoubleEqual(fractial, 0.5f)) - ? 1.0f - : 0.0f); + (!YGDoubleIsUndefined(fractial) && + (fractial > 0.5 || YGDoubleEqual(fractial, 0.5)) + ? 1.0 + : 0.0); } - return (YGFloatIsUndefined(scaledValue) || - YGFloatIsUndefined(pointScaleFactor)) + return (YGDoubleIsUndefined(scaledValue) || + YGDoubleIsUndefined(pointScaleFactor)) ? YGUndefined - : scaledValue / pointScaleFactor; + : (float) (scaledValue / pointScaleFactor); } YOGA_EXPORT bool YGNodeCanUseCachedMeasurement( From 6c2ba945be91cee985a0738552e960f3ed2059d8 Mon Sep 17 00:00:00 2001 From: Altaibayar Tseveenbayar Date: Mon, 22 Mar 2021 04:31:18 -0700 Subject: [PATCH 77/87] Making yoga by default a static library Summary: We are linking yoga as a static library in most of the places Reviewed By: SidharthGuglani Differential Revision: D27228933 fbshipit-source-id: 725d6551198c96925ae80b3a62ef9737ee7e3052 --- csharp/Yoga/Yoga.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/Yoga/Yoga.vcxproj b/csharp/Yoga/Yoga.vcxproj index 0bb66327..306e8e15 100755 --- a/csharp/Yoga/Yoga.vcxproj +++ b/csharp/Yoga/Yoga.vcxproj @@ -36,7 +36,7 @@ - DynamicLibrary + StaticLibrary true v141 Unicode From 638690255c24c2d1a6e644b4f2694643408db228 Mon Sep 17 00:00:00 2001 From: Altaibayar Tseveenbayar Date: Mon, 22 Mar 2021 07:41:16 -0700 Subject: [PATCH 78/87] Yoga set as a static library also for debug+release builds in x64 Summary: Yoga set as a static library also for debug+release builds in x64 Reviewed By: SidharthGuglani Differential Revision: D27230019 fbshipit-source-id: d77e2c4130cd8303d1585723bfad927b9ddba23e --- csharp/Yoga/Yoga.vcxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/Yoga/Yoga.vcxproj b/csharp/Yoga/Yoga.vcxproj index 306e8e15..974919de 100755 --- a/csharp/Yoga/Yoga.vcxproj +++ b/csharp/Yoga/Yoga.vcxproj @@ -48,7 +48,7 @@ Unicode - DynamicLibrary + StaticLibrary false v141 true @@ -62,13 +62,13 @@ Unicode - DynamicLibrary + StaticLibrary true v141 Unicode - DynamicLibrary + StaticLibrary false v141 true From 07eaeea7a4e5cfe6f0a1da2cb24d5603613a6d25 Mon Sep 17 00:00:00 2001 From: Aditya Sharat Date: Fri, 26 Mar 2021 10:04:04 -0700 Subject: [PATCH 79/87] Create YogaProps Interface Summary: Create YogaProps Interface; this interface represents the inputs to YogaNode for layout calculation. Changelog: [Internal] Create YogaProps Interface; this interface represents the inputs to YogaNode for layout calculation. Reviewed By: mihaelao Differential Revision: D27229274 fbshipit-source-id: 5205caf2384661369d7a2d7e7f3e49ff831a1c92 --- java/com/facebook/yoga/YogaNode.java | 2 +- java/com/facebook/yoga/YogaProps.java | 151 ++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 java/com/facebook/yoga/YogaProps.java diff --git a/java/com/facebook/yoga/YogaNode.java b/java/com/facebook/yoga/YogaNode.java index dfec8ec5..542d36bf 100644 --- a/java/com/facebook/yoga/YogaNode.java +++ b/java/com/facebook/yoga/YogaNode.java @@ -9,7 +9,7 @@ package com.facebook.yoga; import javax.annotation.Nullable; -public abstract class YogaNode { +public abstract class YogaNode implements YogaProps { /** The interface the {@link #getData()} object can optionally implement. */ public interface Inputs { diff --git a/java/com/facebook/yoga/YogaProps.java b/java/com/facebook/yoga/YogaProps.java new file mode 100644 index 00000000..9faa520f --- /dev/null +++ b/java/com/facebook/yoga/YogaProps.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) Facebook, Inc. and its 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.yoga; + +public interface YogaProps { + + /* Width properties */ + + void setWidth(float width); + + void setWidthPercent(float percent); + + void setMinWidth(float minWidth); + + void setMinWidthPercent(float percent); + + void setMaxWidth(float maxWidth); + + void setMaxWidthPercent(float percent); + + void setWidthAuto(); + + /* Height properties */ + + void setHeight(float height); + + void setHeightPercent(float percent); + + void setMinHeight(float minHeight); + + void setMinHeightPercent(float percent); + + void setMaxHeight(float maxHeight); + + void setMaxHeightPercent(float percent); + + void setHeightAuto(); + + /* Margin properties */ + + void setMargin(YogaEdge edge, float margin); + + void setMarginPercent(YogaEdge edge, float percent); + + void setMarginAuto(YogaEdge edge); + + /* Padding properties */ + + void setPadding(YogaEdge edge, float padding); + + void setPaddingPercent(YogaEdge edge, float percent); + + /* Position properties */ + + void setPositionType(YogaPositionType positionType); + + void setPosition(YogaEdge edge, float position); + + void setPositionPercent(YogaEdge edge, float percent); + + /* Alignment properties */ + + void setAlignContent(YogaAlign alignContent); + + void setAlignItems(YogaAlign alignItems); + + void setAlignSelf(YogaAlign alignSelf); + + /* Flex properties */ + + void setFlex(float flex); + + void setFlexBasisAuto(); + + void setFlexBasisPercent(float percent); + + void setFlexBasis(float flexBasis); + + void setFlexDirection(YogaFlexDirection direction); + + void setFlexGrow(float flexGrow); + + void setFlexShrink(float flexShrink); + + /* Other properties */ + + void setJustifyContent(YogaJustify justifyContent); + + void setDirection(YogaDirection direction); + + void setBorder(YogaEdge edge, float value); + + void setWrap(YogaWrap wrap); + + void setAspectRatio(float aspectRatio); + + void setIsReferenceBaseline(boolean isReferenceBaseline); + + void setMeasureFunction(YogaMeasureFunction measureFunction); + + void setBaselineFunction(YogaBaselineFunction yogaBaselineFunction); + + /* Getters */ + + YogaValue getWidth(); + + YogaValue getMinWidth(); + + YogaValue getMaxWidth(); + + YogaValue getHeight(); + + YogaValue getMinHeight(); + + YogaValue getMaxHeight(); + + YogaDirection getStyleDirection(); + + YogaFlexDirection getFlexDirection(); + + YogaJustify getJustifyContent(); + + YogaAlign getAlignItems(); + + YogaAlign getAlignSelf(); + + YogaAlign getAlignContent(); + + YogaPositionType getPositionType(); + + float getFlexGrow(); + + float getFlexShrink(); + + YogaValue getFlexBasis(); + + float getAspectRatio(); + + YogaValue getMargin(YogaEdge edge); + + YogaValue getPadding(YogaEdge edge); + + YogaValue getPosition(YogaEdge edge); + + float getBorder(YogaEdge edge); +} From cbf6495d66a7a8066d1354daa14d3bb1af19f6ef Mon Sep 17 00:00:00 2001 From: Aditya Sharat Date: Tue, 30 Mar 2021 05:41:22 -0700 Subject: [PATCH 80/87] Refactor YogaNode.Inputs freeze API Summary: `InternalNode` will eventually not have a pointer to its parent. This diff removes one of the usages of the `InternalNode#getParent()` API. `InternalNode` will also not host the `YogaNode` eventually; so this diff also removes one of the usages of the `InternalNode#getYogaNode()` api. Now the `Inputs#freeze` api will pass the parent's `YogaNode` and the `YogaNode` of the node (this) being measured. Changelog: [Internal] Passes The YogaNode and parent YogaNode in the Inputs.freeze API Reviewed By: SidharthGuglani Differential Revision: D27240229 fbshipit-source-id: efc4ec3249a963c3181111f9b989d8ed9e17feb4 --- java/com/facebook/yoga/YogaNode.java | 2 +- java/com/facebook/yoga/YogaNodeJNIBase.java | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/java/com/facebook/yoga/YogaNode.java b/java/com/facebook/yoga/YogaNode.java index 542d36bf..109172ee 100644 --- a/java/com/facebook/yoga/YogaNode.java +++ b/java/com/facebook/yoga/YogaNode.java @@ -15,7 +15,7 @@ public abstract class YogaNode implements YogaProps { public interface Inputs { /** Requests the data object to disable mutations of its inputs. */ - void freeze(); + void freeze(final YogaNode node, final @Nullable YogaNode parent); } public abstract void reset(); diff --git a/java/com/facebook/yoga/YogaNodeJNIBase.java b/java/com/facebook/yoga/YogaNodeJNIBase.java index 03354556..7efb8ce1 100644 --- a/java/com/facebook/yoga/YogaNodeJNIBase.java +++ b/java/com/facebook/yoga/YogaNodeJNIBase.java @@ -197,15 +197,16 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { long[] nativePointers = null; YogaNodeJNIBase[] nodes = null; - freeze(); + freeze(null); ArrayList n = new ArrayList<>(); n.add(this); for (int i = 0; i < n.size(); ++i) { - List children = n.get(i).mChildren; + final YogaNodeJNIBase parent = n.get(i); + List children = parent.mChildren; if (children != null) { for (YogaNodeJNIBase child : children) { - child.freeze(); + child.freeze(parent); n.add(child); } } @@ -220,10 +221,10 @@ public abstract class YogaNodeJNIBase extends YogaNode implements Cloneable { YogaNative.jni_YGNodeCalculateLayoutJNI(mNativePointer, width, height, nativePointers, nodes); } - private void freeze() { + private void freeze(YogaNode parent) { Object data = getData(); if (data instanceof Inputs) { - ((Inputs) data).freeze(); + ((Inputs) data).freeze(this, parent); } } From a999150c19415c5b40e941da528bc924fb1d73ad Mon Sep 17 00:00:00 2001 From: Andres Suarez Date: Thu, 20 May 2021 21:22:47 -0700 Subject: [PATCH 81/87] Apply clang-format Reviewed By: igorsugak Differential Revision: D28477074 fbshipit-source-id: f15dfc45b9fb30c661ebe2899cd882676d0fdf2a --- java/jni/YGJNIVanilla.cpp | 3 +-- tests/YGLoggerTest.cpp | 9 +++------ yoga/Yoga.cpp | 8 ++------ 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index 65343821..3503be40 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -726,8 +726,7 @@ static void jni_YGNodePrintJNI(JNIEnv* env, jobject obj, jlong nativePointer) { const YGNodeRef node = _jlong2YGNodeRef(nativePointer); YGNodePrint( node, - (YGPrintOptions)( - YGPrintOptionsStyle | YGPrintOptionsLayout | YGPrintOptionsChildren)); + (YGPrintOptions) (YGPrintOptionsStyle | YGPrintOptionsLayout | YGPrintOptionsChildren)); #endif } diff --git a/tests/YGLoggerTest.cpp b/tests/YGLoggerTest.cpp index 5c319ba6..f9d8002c 100644 --- a/tests/YGLoggerTest.cpp +++ b/tests/YGLoggerTest.cpp @@ -73,8 +73,7 @@ TEST(YogaTest, logger_default_node_should_print_no_style_info) { YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR); YGNodePrint( root, - (YGPrintOptions)( - YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); + (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); YGConfigSetLogger(config, NULL); YGNodeFree(root); @@ -98,8 +97,7 @@ TEST(YogaTest, logger_node_with_percentage_absolute_position_and_margin) { YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR); YGNodePrint( root, - (YGPrintOptions)( - YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); + (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); YGConfigSetLogger(config, NULL); YGNodeFree(root); @@ -122,8 +120,7 @@ TEST(YogaTest, logger_node_with_children_should_print_indented) { YGNodeCalculateLayout(root, YGUnitUndefined, YGUnitUndefined, YGDirectionLTR); YGNodePrint( root, - (YGPrintOptions)( - YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); + (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); YGConfigSetLogger(config, NULL); YGNodeFreeRecursive(root); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 33f70e82..2c68674a 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -4194,9 +4194,7 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( if (node->getConfig()->printTree) { YGNodePrint( node, - (YGPrintOptions)( - YGPrintOptionsLayout | YGPrintOptionsChildren | - YGPrintOptionsStyle)); + (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); } #endif } @@ -4256,9 +4254,7 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( if (nodeWithoutLegacyFlag->getConfig()->printTree) { YGNodePrint( nodeWithoutLegacyFlag, - (YGPrintOptions)( - YGPrintOptionsLayout | YGPrintOptionsChildren | - YGPrintOptionsStyle)); + (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); } #endif } From 508f4eacdf430cec8f163884c6c107dd80ec4712 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Fri, 21 May 2021 10:10:34 -0700 Subject: [PATCH 82/87] Fix env setting and Android setup (#1085) Summary: *Context: The Yoga OSS build has not been given a lot of attention over the past couple of years and is in serious disrepair. I'll try to get the release pipeline going again to publish to Maven Central as JCenter is shutting down. A bunch of intermediate commits may still have broken builds but will be inching closer to a working one.* The current way env variables are set is no longer supported for security reasons: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/. The manual Android setup is also quite tricky to maintain and can mostly be done through GitHub Actions itself. Please note that the actual build is still failing but that's because we're so far behind with the setup here that the Gradle version no longer works on a modern JVM. I'll fix that in subsequent diffs. Pull Request resolved: https://github.com/facebook/yoga/pull/1085 Test Plan: CI Reviewed By: mweststrate Differential Revision: D28602084 Pulled By: passy fbshipit-source-id: e334ed92d16a9baa185a84b23bb62801399e5650 --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5f2c014..2c9152f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,13 +44,8 @@ jobs: cd buck ant popd - echo "::set-env name=PATH::$PATH:$HOME/buck/bin/" + echo "$HOME/buck/bin" >> $GITHUB_PATH export PATH=$PATH:$HOME/buck/bin/ buck --version - export TERMINAL=dumb - source scripts/android-setup.sh && installAndroidSDK - echo "::set-env name=ANDROID_SDK::$ANDROID_HOME" - echo "::set-env name=ANDROID_NDK_REPOSITORY::$HOME/android-ndk" - echo "::set-env name=ANDROID_NDK_HOME::$ANDROID_NDK_REPOSITORY/android-ndk-r15c" - name: Build run: ./gradlew testDebugUnit && scripts/publish-snapshot.sh From 13e079e8f32430d37043a4c1c1ef584ee87db7fb Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Fri, 21 May 2021 11:14:07 -0700 Subject: [PATCH 83/87] Upgrade Gradle setup (#1084) Summary: Trying to dust off the build setup and make it work again with a modern Android Studio / JVM. Removing all JCenter setup, too, as this is no longer supported. Pull Request resolved: https://github.com/facebook/yoga/pull/1084 Test Plan: `./gradlew :yoga-layout:assembleDebug` works already. Looking if CI here likes this. Reviewed By: mweststrate Differential Revision: D28602272 Pulled By: passy fbshipit-source-id: 0cb86f548cc6366ccefcc92c185d6e7772e75547 --- .github/workflows/ci.yml | 9 ++- .gitignore | 3 + android/build.gradle | 26 +------ build.gradle | 15 ++-- gradle/android-maven-install.gradle | 44 ----------- gradle/android-tasks.gradle | 54 ------------- gradle/bintray.gradle | 70 ----------------- gradle/gradle-mvn-push.gradle | 96 ------------------------ gradle/release-bintray.gradle | 40 ---------- gradle/release.gradle | 15 ---- gradle/wrapper/gradle-wrapper.properties | 2 +- java/build.gradle | 31 +------- java/proguard-annotations/build.gradle | 2 - scripts/publish-snapshot.sh | 13 +--- 14 files changed, 22 insertions(+), 398 deletions(-) delete mode 100644 gradle/android-maven-install.gradle delete mode 100644 gradle/android-tasks.gradle delete mode 100644 gradle/bintray.gradle delete mode 100644 gradle/gradle-mvn-push.gradle delete mode 100644 gradle/release-bintray.gradle delete mode 100644 gradle/release.gradle diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c9152f0..900c34d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Install NDK 21 + run: echo "y" | sudo /usr/local/lib/android/sdk/tools/bin/sdkmanager --install "ndk;21.0.6113669" "ndk;20.0.5594570" --sdk_root=${ANDROID_SDK_ROOT} - name: Install dependencies run: | if [[ -n "${{ secrets.encrypted_d27e803291ff_iv }}" ]]; then @@ -48,4 +54,5 @@ jobs: export PATH=$PATH:$HOME/buck/bin/ buck --version - name: Build - run: ./gradlew testDebugUnit && scripts/publish-snapshot.sh + # TODO: Run the tests here again. They're currently crashing the JVM in GitHub Actions for some reason. + run: ./gradlew :yoga-layout:assembleDebug && scripts/publish-snapshot.sh diff --git a/.gitignore b/.gitignore index c4a6bf0f..44f230ed 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ /.buckd /gentest/test.html .buckversion +.cxx +.idea +/local.properties # Jekyll /.sass-cache/ diff --git a/android/build.gradle b/android/build.gradle index 775cdc82..fb0d22af 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,17 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -apply plugin: 'com.jfrog.bintray' apply plugin: 'com.android.library' -apply plugin: 'com.github.dcendents.android-maven' -apply plugin: 'maven-publish' - -version = VERSION_NAME -group = GROUP android { compileSdkVersion rootProject.compileSdkVersion buildToolsVersion rootProject.buildToolsVersion + ndkVersion rootProject.ndkVersion defaultConfig { minSdkVersion rootProject.minSdkVersion @@ -31,22 +26,3 @@ android { dependencies { api project(':yoga') } - -task sourcesJar(type: Jar) { - classifier = 'source' - from android.sourceSets.main.java.srcDirs -} - -task javadoc(type: Javadoc) { - failOnError false - source = android.sourceSets.main.java.sourceFiles - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - classpath += configurations.compile -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -apply from: rootProject.file('gradle/release.gradle') diff --git a/build.gradle b/build.gradle index ff6f028a..2b8ee97e 100644 --- a/build.gradle +++ b/build.gradle @@ -10,14 +10,10 @@ buildscript { repositories { google() - jcenter() - maven { url 'https://maven.google.com/' } + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.0' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' - classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' - + classpath 'com.android.tools.build:gradle:4.2.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -32,9 +28,10 @@ allprojects { ext { minSdkVersion = 14 - targetSdkVersion = 25 - compileSdkVersion = 26 - buildToolsVersion = '28.0.3' + targetSdkVersion = 29 + compileSdkVersion = 29 + buildToolsVersion = '30.0.2' + ndkVersion = '21.3.6528147' sourceCompatibilityVersion = JavaVersion.VERSION_1_7 targetCompatibilityVersion = JavaVersion.VERSION_1_7 } diff --git a/gradle/android-maven-install.gradle b/gradle/android-maven-install.gradle deleted file mode 100644 index a5e7b823..00000000 --- a/gradle/android-maven-install.gradle +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// Configure the Android maven publication - -apply plugin: 'com.github.dcendents.android-maven' - -version = VERSION_NAME -group = GROUP -// Set the .aar / .jar base file name to match the artifact ID -// in case the module has a different name -project.archivesBaseName = POM_ARTIFACT_ID - -install { - repositories.mavenInstaller { - // This generates POM.xml with proper parameters - pom.project { - name POM_NAME - artifactId POM_ARTIFACT_ID - packaging POM_PACKAGING - description POM_DESCRIPTION - url projectUrl - - scm { - url scmUrl - connection scmConnection - developerConnection scmDeveloperConnection - } - - licenses projectLicenses - - developers { - developer { - id developerId - name developerName - } - } - } - } -} diff --git a/gradle/android-tasks.gradle b/gradle/android-tasks.gradle deleted file mode 100644 index 9e7028a9..00000000 --- a/gradle/android-tasks.gradle +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// Android tasks for Javadoc and sources.jar generation - -afterEvaluate { project -> - if (POM_PACKAGING == 'aar') { - task androidJavadoc(type: Javadoc) { - source = android.sourceSets.main.java.srcDirs - exclude '**/pom.xml' - exclude '**/proguard_annotations.pro' - classpath += files(android.bootClasspath) - } - - task androidJavadocJar(type: Jar) { - classifier = 'javadoc' - from androidJavadoc.destinationDir - } - - task androidSourcesJar(type: Jar) { - classifier = 'sources' - from android.sourceSets.main.java.srcDirs - } - - android.libraryVariants.all { variant -> - def name = variant.name.capitalize() - task "jar${name}"(type: Jar, dependsOn: variant.javaCompile) { - from variant.javaCompile.destinationDir - } - } - - artifacts.add('archives', androidJavadocJar) - artifacts.add('archives', androidSourcesJar) - } - - if (POM_PACKAGING == 'jar') { - task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir - } - - task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource - } - - artifacts.add('archives', javadocJar) - artifacts.add('archives', sourcesJar) - } -} diff --git a/gradle/bintray.gradle b/gradle/bintray.gradle deleted file mode 100644 index 20262c13..00000000 --- a/gradle/bintray.gradle +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// Upload to Bintray -apply plugin: 'com.jfrog.bintray' - -def getBintrayUsername() { - return project.hasProperty('bintrayUsername') ? property('bintrayUsername') : System.getenv('BINTRAY_USERNAME') -} - -def getBintrayApiKey() { - return project.hasProperty('bintrayApiKey') ? property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') -} - -def getBintrayGpgPassword() { - return project.hasProperty('bintrayGpgPassword') ? property('bintrayGpgPassword') : System.getenv('BINTRAY_GPG_PASSWORD') -} - -def getMavenCentralUsername() { - return project.hasProperty('mavenCentralUsername') ? property('mavenCentralUsername') : System.getenv('MAVEN_CENTRAL_USERNAME') -} - -def getMavenCentralPassword() { - return project.hasProperty('mavenCentralPassword') ? property('mavenCentralPassword') : System.getenv('MAVEN_CENTRAL_PASSWORD') -} - -def shouldSyncWithMavenCentral() { - return project.hasProperty('syncWithMavenCentral') ? property('syncWithMavenCentral').toBoolean() : false -} - -def dryRunOnly() { - return project.hasProperty('dryRun') ? property('dryRun').toBoolean() : false -} - -bintray { - user = getBintrayUsername() - key = getBintrayApiKey() - configurations = ['archives'] - pkg { - repo = bintrayRepo - userOrg = bintrayUserOrg - name = bintrayName - desc = bintrayDescription - websiteUrl = projectUrl - issueTrackerUrl = issuesUrl - vcsUrl = scmUrl - licenses = projectLicenses - dryRun = dryRunOnly() - override = true - publish = true - publicDownloadNumbers = true - version { - desc = bintrayDescription - gpg { - sign = true - passphrase = getBintrayGpgPassword() - } - mavenCentralSync { - sync = shouldSyncWithMavenCentral() - user = getMavenCentralUsername() - password = getMavenCentralPassword() - close = '1' // If set to 0, you have to manually click release - } - } - } -} diff --git a/gradle/gradle-mvn-push.gradle b/gradle/gradle-mvn-push.gradle deleted file mode 100644 index f7b6f1a1..00000000 --- a/gradle/gradle-mvn-push.gradle +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013 Chris Banes - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -apply plugin: 'signing' - -version = VERSION_NAME -group = GROUP - -def isReleaseBuild() { - return VERSION_NAME.contains('SNAPSHOT') == false -} - -def getReleaseRepositoryUrl() { - return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL - : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" -} - -def getSnapshotRepositoryUrl() { - return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL - : "https://oss.sonatype.org/content/repositories/snapshots/" -} - -def getRepositoryUsername() { - return hasProperty('SONATYPE_NEXUS_USERNAME') ? SONATYPE_NEXUS_USERNAME : "" -} - -def getRepositoryPassword() { - return hasProperty('SONATYPE_NEXUS_PASSWORD') ? SONATYPE_NEXUS_PASSWORD : "" -} - -afterEvaluate { project -> - uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - pom.groupId = GROUP - pom.artifactId = POM_ARTIFACT_ID - pom.version = VERSION_NAME - - repository(url: getReleaseRepositoryUrl()) { - authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) - } - snapshotRepository(url: getSnapshotRepositoryUrl()) { - authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) - } - - pom.project { - name POM_NAME - packaging POM_PACKAGING - description POM_DESCRIPTION - url POM_URL - - scm { - url POM_SCM_URL - connection POM_SCM_CONNECTION - developerConnection POM_SCM_DEV_CONNECTION - } - - licenses { - license { - name POM_LICENSE_NAME - url POM_LICENSE_URL - distribution POM_LICENSE_DIST - } - } - - developers { - developer { - id POM_DEVELOPER_ID - name POM_DEVELOPER_NAME - } - } - } - } - } - } - - signing { - required { isReleaseBuild() && gradle.taskGraph.hasTask('uploadArchives') } - sign configurations.archives - } -} diff --git a/gradle/release-bintray.gradle b/gradle/release-bintray.gradle deleted file mode 100644 index 1c6e6891..00000000 --- a/gradle/release-bintray.gradle +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// Set up everything required for releasing on Bintray -ext { - bintrayRepo = 'maven' - bintrayUserOrg = 'facebook' - bintrayName = "${GROUP}:${POM_ARTIFACT_ID}" - bintrayDescription = POM_DESCRIPTION - projectUrl = POM_URL - issuesUrl = 'https://github.com/facebook/yoga/issues' - scmUrl = POM_SCM_URL - scmConnection = POM_SCM_CONNECTION - scmDeveloperConnection = POM_SCM_DEV_CONNECTION - - publishedGroupId = GROUP - libraryName = 'yoga' - artifact = 'yoga' - - developerId = POM_DEVELOPER_ID - developerName = POM_DEVELOPER_NAME - - projectLicenses = { - license { - name = POM_LICENSE_NAME - url = POM_LICENSE_URL - distribution = POM_LICENSE_DIST - } - } -} - -// Set up the Android Maven publication (POM etc.) -apply from: rootProject.file('gradle/android-maven-install.gradle') - -// Upload to Bintray -apply from: rootProject.file('gradle/bintray.gradle') diff --git a/gradle/release.gradle b/gradle/release.gradle deleted file mode 100644 index b63d0f2e..00000000 --- a/gradle/release.gradle +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// Common Android tasks for all releases that generate Javadocs, sources, etc. -apply from: rootProject.file('gradle/android-tasks.gradle') - -// Upload to Bintray -apply from: rootProject.file('gradle/release-bintray.gradle') - -// Upload directly to standard Maven Central (for SNAPSHOTs) -apply from: rootProject.file('gradle/gradle-mvn-push.gradle') diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8772300a..7ff90540 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip diff --git a/java/build.gradle b/java/build.gradle index 7c404c17..b749f477 100644 --- a/java/build.gradle +++ b/java/build.gradle @@ -5,17 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -apply plugin: 'com.jfrog.bintray' apply plugin: 'com.android.library' -apply plugin: 'com.github.dcendents.android-maven' -apply plugin: 'maven-publish' - -group = GROUP -version = VERSION_NAME android { compileSdkVersion rootProject.compileSdkVersion buildToolsVersion rootProject.buildToolsVersion + ndkVersion rootProject.ndkVersion defaultConfig { minSdkVersion rootProject.minSdkVersion @@ -35,7 +30,6 @@ android { externalNativeBuild { cmake { path 'CMakeLists.txt' - version '3.6.0-rc2' } } @@ -64,26 +58,3 @@ dependencies { testImplementation 'junit:junit:4.12' testImplementation project(':testutil') } - -task sourcesJar(type: Jar) { - classifier = 'source' - from android.sourceSets.main.java.srcDirs -} - -task javadoc(type: Javadoc) { - failOnError false - source = android.sourceSets.main.java.sourceFiles - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - classpath += configurations.compile -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -ext { - bintrayName = 'com.facebook.yoga:yoga' -} - -apply from: rootProject.file('gradle/release.gradle') diff --git a/java/proguard-annotations/build.gradle b/java/proguard-annotations/build.gradle index c4476d9e..8f4a88ac 100644 --- a/java/proguard-annotations/build.gradle +++ b/java/proguard-annotations/build.gradle @@ -9,5 +9,3 @@ apply plugin: 'java' sourceCompatibility = '1.7' targetCompatibility = '1.7' - -apply from: rootProject.file('gradle/release.gradle') diff --git a/scripts/publish-snapshot.sh b/scripts/publish-snapshot.sh index c494f97f..236d8055 100755 --- a/scripts/publish-snapshot.sh +++ b/scripts/publish-snapshot.sh @@ -14,17 +14,8 @@ set -e BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" IS_SNAPSHOT="$(grep 'VERSION_NAME=[0-9\.]\+-SNAPSHOT' "$BASEDIR/gradle.properties")" -if [ "$GITHUB_REPOSITORY" != "facebook/yoga" ]; then - echo >&2 "Skipping repository. Expected project to be 'facebook/yoga', but was '$GITHUB_REPOSITORY'." - exit -elif [ "$GITHUB_REF" != "refs/heads/master" ]; then - echo >&2 "Skipping build. Expected ref name to be 'refs/heads/master', but was '$GITHUB_REF'." - exit -elif [ "$GITHUB_EVENT_NAME" != "push" ]; then - echo >&2 "Skipping build. Only considering push builds, but event was '$GITHUB_EVENT_NAME'." - exit -elif [ "$IS_SNAPSHOT" == "" ]; then +if [ "$IS_SNAPSHOT" == "" ]; then echo >&2 "Skipping build. Given build doesn't appear to be a SNAPSHOT release." else - env TERMINAL=dumb "$BASEDIR/gradlew" uploadArchives + env TERMINAL=dumb "$BASEDIR/gradlew" publish fi From e3a59aa50ee60e6ceaa6df87cdf56409a05dc064 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Fri, 21 May 2021 11:40:17 -0700 Subject: [PATCH 84/87] Maven central publish (#1086) Summary: Sets up the plugins necessary to publish to Maven Central. Pull Request resolved: https://github.com/facebook/yoga/pull/1086 Test Plan: ./gradlew publishToMavenLocal -PRELEASE_SIGNING_ENABLED=false Reviewed By: mweststrate Differential Revision: D28604529 Pulled By: passy fbshipit-source-id: 2c35b94ce0e254bc7a8bc80e449ac5dadb5def38 --- android/build.gradle | 8 ++++++++ build.gradle | 3 ++- gradle.properties | 5 ++++- java/build.gradle | 6 ++++-- java/proguard-annotations/build.gradle | 2 ++ lib/fb/build.gradle | 4 ++-- testutil/build.gradle | 3 +-- 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index fb0d22af..a29aac17 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -26,3 +26,11 @@ android { dependencies { api project(':yoga') } + +// We don't build Javadoc at this time as we can't disable "BUCK" files +// from mistakenly getting parsed as Java. +tasks.withType(Javadoc).all { + enabled = false +} + +apply plugin: 'com.vanniktech.maven.publish' diff --git a/build.gradle b/build.gradle index 2b8ee97e..26610432 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:4.2.1' + classpath 'com.vanniktech:gradle-maven-publish-plugin:0.15.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -22,7 +23,7 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() } } diff --git a/gradle.properties b/gradle.properties index 382f62fa..d5653873 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.jvmargs=-Xmx1536M -VERSION_NAME=1.17.0-SNAPSHOT +VERSION_NAME=1.19.0 POM_URL=https://github.com/facebook/yoga POM_SCM_URL=https://github.com/facebook/yoga.git POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git @@ -17,5 +17,8 @@ POM_SCM_DEV_CONNECTION=scm:git:git@github.com:facebook/yoga.git POM_LICENSE_NAME=MIT License POM_LICENSE_URL=https://github.com/facebook/yoga/blob/master/LICENSE POM_LICENSE_DIST=repo +POM_LICENCE_NAME=MIT License +POM_LICENCE_URL=https://github.com/facebook/yoga/blob/master/LICENSE +POM_LICENCE_DIST=repo POM_DEVELOPER_ID=facebook POM_DEVELOPER_NAME=facebook diff --git a/java/build.gradle b/java/build.gradle index b749f477..8d78a03f 100644 --- a/java/build.gradle +++ b/java/build.gradle @@ -52,9 +52,11 @@ android { } dependencies { - implementation 'com.google.code.findbugs:jsr305:3.0.1' + implementation 'com.google.code.findbugs:jsr305:3.0.2' implementation project(':yoga:proguard-annotations') - implementation 'com.facebook.soloader:soloader:0.5.1' + implementation 'com.facebook.soloader:soloader:0.10.1' testImplementation 'junit:junit:4.12' testImplementation project(':testutil') } + +apply plugin: 'com.vanniktech.maven.publish' diff --git a/java/proguard-annotations/build.gradle b/java/proguard-annotations/build.gradle index 8f4a88ac..97754e99 100644 --- a/java/proguard-annotations/build.gradle +++ b/java/proguard-annotations/build.gradle @@ -9,3 +9,5 @@ apply plugin: 'java' sourceCompatibility = '1.7' targetCompatibility = '1.7' + +apply plugin: 'com.vanniktech.maven.publish' diff --git a/lib/fb/build.gradle b/lib/fb/build.gradle index d5e5e202..a3495d8f 100644 --- a/lib/fb/build.gradle +++ b/lib/fb/build.gradle @@ -33,8 +33,8 @@ android { } dependencies { - implementation 'com.facebook.soloader:soloader:0.5.1' - implementation 'com.google.code.findbugs:jsr305:3.0.1' + implementation 'com.facebook.soloader:soloader:0.10.1' + implementation 'com.google.code.findbugs:jsr305:3.0.2' implementation project(':yoga:proguard-annotations') } } diff --git a/testutil/build.gradle b/testutil/build.gradle index 647d66d3..d36e8673 100644 --- a/testutil/build.gradle +++ b/testutil/build.gradle @@ -29,11 +29,10 @@ android { externalNativeBuild { cmake { path 'src/main/cpp/CMakeLists.txt' - version '3.6.0-rc2' } } dependencies { - implementation 'com.facebook.soloader:soloader:0.5.1' + implementation 'com.facebook.soloader:soloader:0.10.1' } } From 0fcef77d7bf793fe7ff139288bf41528ea551504 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Fri, 21 May 2021 11:40:17 -0700 Subject: [PATCH 85/87] Maven release docs (#1087) Summary: *Context: The Yoga OSS build has not been given a lot of attention over the past couple of years and is in serious disrepair. I'll try to get the release pipeline going again to publish to Maven Central as JCenter is shutting down. A bunch of intermediate commits may still have broken builds but will be inching closer to a working one.* Adds some docs on how to use the release workflow. Pull Request resolved: https://github.com/facebook/yoga/pull/1087 Reviewed By: priteshrnandgaonkar Differential Revision: D28604686 Pulled By: passy fbshipit-source-id: 44cac2cd0593a4f71d80df1ec5324c3c27fbe888 --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 689851d6..527879ff 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,29 @@ This will now only run the standalone webpack build upon install. | node | Builds node js version. | | standalone | Runs webpack. | | none | Does nothing. You can use the prepackaged libs. | + +## Maintainer Release Guide + +To publish a new release, follow these steps: + +1. Ensure you have your GPG key set up and your [OSS Sonatype](https://oss.sonatype.org/) credentials handy. +2. Add the follow entries to either your local `gradle.properties` (don't forget to revert) or your global `~/.gradle/gradle.properties`: + +``` +# You get these from https://oss.sonatype.org/#profile;User%20Token +mavenCentralRepositoryUsername= +mavenCentralRepositoryPassword= + +# You can get the keyId (in GPG 1.4 format) by running `gpg1 --list-keys`. +signing.secretKeyRingFile= +signing.keyId= +signing.password= +``` + +3. Change the `VERSION_NAME` in `gradle.properties` to a non-SNAPSHOT release. +4. Commit and land the version change. +5. Run `./gradlew publishToMaven`. +6. Run `./gradlew closeAndReleaseRepository`. +7. Change the `VERSION_NAME` in `gradle.properties` back to a new SNAPSHOT release. +8. Commit and land the version change. +9. Celebrate! You've made a release! From 8a65d8b6dc65fbe71d3fdfc0d4274fc3d7b0452d Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Fri, 21 May 2021 11:40:17 -0700 Subject: [PATCH 86/87] Release GitHub actions workflow (#1088) Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1088 Reviewed By: mweststrate Differential Revision: D28604872 Pulled By: passy fbshipit-source-id: e77578d44557420be9b782dc90f047af697b7cb9 --- .github/workflows/release.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..1231fb66 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,32 @@ +name: Publish + +on: + release: + types: + - created + workflow_dispatch: + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Install dependencies + run: source scripts/android-setup.sh && installAndroidSDK + - name: Write GPG Sec Ring + run: echo '${{ secrets.GPG_KEY_CONTENTS }}' | base64 -d > /tmp/secring.gpg + - name: Update gradle.properties + run: echo -e "signing.secretKeyRingFile=/tmp/secring.gpg\nsigning.keyId=${{ secrets.SIGNING_KEY_ID }}\nsigning.password=${{ secrets.SIGNING_PASSWORD }}\nmavenCentralPassword=${{ secrets.SONATYPE_NEXUS_PASSWORD }}\nmavenCentralUsername=${{ secrets.SONATYPE_NEXUS_USERNAME }}" >> gradle.properties + - name: Upload Android Archives + run: ./gradlew :yoga:assembleRelease publish --info + - name: Release and close + run: ./gradlew closeAndReleaseRepository + - name: Clean secrets + if: always() + run: rm /tmp/secring.gpg From f03129728f591b311fbf99615f9e75b8c4e068f9 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Sun, 23 May 2021 11:37:42 -0700 Subject: [PATCH 87/87] Disable snapshot publishing (#1089) Summary: Currently broken. Will reenable this separately. Pull Request resolved: https://github.com/facebook/yoga/pull/1089 Reviewed By: mweststrate Differential Revision: D28609885 Pulled By: passy fbshipit-source-id: 380359d09ee96d321d49c6440bde358c3e791c1a --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 900c34d9..239ffece 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,4 +55,4 @@ jobs: buck --version - name: Build # TODO: Run the tests here again. They're currently crashing the JVM in GitHub Actions for some reason. - run: ./gradlew :yoga-layout:assembleDebug && scripts/publish-snapshot.sh + run: ./gradlew :yoga-layout:assembleDebug