Add sealing assertion in fabric

Summary: This diff checks if ReactShadowNode is sealed before updaing it.

Reviewed By: fkgozali

Differential Revision: D8584768

fbshipit-source-id: 64163d4bf124263d92153f68914c617f007fd90d
This commit is contained in:
David Vacca 2018-06-22 11:29:09 -07:00 committed by Facebook Github Bot
parent 001e217f33
commit 93b568cc51
2 changed files with 73 additions and 7 deletions

View File

@ -451,7 +451,7 @@ public class FabricUIManager implements UIManager, JSHandler {
}
int tag = node.getReactTag();
if (mRootShadowNodeRegistry.getNode(tag) == null) {
if (getRootNode(tag) == null) {
boolean frameDidChange =
node.dispatchUpdates(absoluteX, absoluteY, mUIViewOperationQueue, null);
// Notify JS about layout event if requested
@ -511,13 +511,16 @@ public class FabricUIManager implements UIManager, JSHandler {
@Override
@DoNotStrip
public void updateRootLayoutSpecs(int rootViewTag, int widthMeasureSpec, int heightMeasureSpec) {
ReactShadowNode rootNode = mRootShadowNodeRegistry.getNode(rootViewTag);
public synchronized void updateRootLayoutSpecs(int rootViewTag, int widthMeasureSpec, int heightMeasureSpec) {
ReactShadowNode rootNode = getRootNode(rootViewTag);
if (rootNode == null) {
FLog.w(ReactConstants.TAG, "Tried to update non-existent root tag: " + rootViewTag);
return;
}
updateRootView(rootNode, widthMeasureSpec, heightMeasureSpec);
ReactShadowNode newRootNode = rootNode.mutableCopy(rootNode.getInstanceHandle());
updateRootView(newRootNode, widthMeasureSpec, heightMeasureSpec);
mRootShadowNodeRegistry.replaceNode(newRootNode);
}
/**
@ -526,18 +529,20 @@ public class FabricUIManager implements UIManager, JSHandler {
* //TODO: change synchronization to integrate with new #render loop.
*/
private synchronized void updateRootSize(int rootTag, int newWidth, int newHeight) {
ReactShadowNode rootNode = mRootShadowNodeRegistry.getNode(rootTag);
ReactShadowNode rootNode = getRootNode(rootTag);
if (rootNode == null) {
FLog.w(
ReactConstants.TAG,
"Tried to update size of non-existent tag: " + rootTag);
return;
}
ReactShadowNode newRootNode = rootNode.mutableCopy(rootNode.getInstanceHandle());
int newWidthSpec = View.MeasureSpec.makeMeasureSpec(newWidth, View.MeasureSpec.EXACTLY);
int newHeightSpec = View.MeasureSpec.makeMeasureSpec(newHeight, View.MeasureSpec.EXACTLY);
updateRootView(rootNode, newWidthSpec, newHeightSpec);
updateRootView(newRootNode, newWidthSpec, newHeightSpec);
completeRoot(rootTag, rootNode.getChildrenList());
completeRoot(rootTag, newRootNode.getChildrenList());
}
public void removeRootView(int rootTag) {

View File

@ -299,6 +299,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public final void markUpdateSeen() {
assertNotSealed();
mNodeUpdated = false;
if (hasNewLayout()) {
markLayoutSeen();
@ -324,6 +325,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void dirty() {
assertNotSealed();
if (!isVirtual()) {
mYogaNode.dirty();
}
@ -336,6 +338,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void addChildAt(ReactShadowNodeImpl child, int i) {
assertNotSealed();
if (mChildren == null) {
mChildren = new ArrayList<>(4);
}
@ -367,6 +370,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public ReactShadowNodeImpl removeChildAt(int i) {
assertNotSealed();
if (mChildren == null) {
throw new ArrayIndexOutOfBoundsException(
"Index " + i + " out of bounds: node has no children");
@ -539,6 +543,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void setReactTag(int reactTag) {
assertNotSealed();
mReactTag = reactTag;
}
@ -550,11 +555,13 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public final void setRootTag(int rootTag) {
assertNotSealed();
mRootTag = rootTag;
}
@Override
public final void setViewClassName(String viewClassName) {
assertNotSealed();
mViewClassName = viewClassName;
}
@ -596,6 +603,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public final void markLayoutSeen() {
assertNotSealed();
if (mYogaNode != null) {
mYogaNode.markLayoutSeen();
}
@ -607,6 +615,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
*/
@Override
public final void addNativeChildAt(ReactShadowNodeImpl child, int nativeIndex) {
assertNotSealed();
Assertions.assertCondition(!mIsLayoutOnly);
Assertions.assertCondition(!child.mIsLayoutOnly);
@ -658,6 +667,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
*/
@Override
public final void setIsLayoutOnly(boolean isLayoutOnly) {
assertNotSealed();
Assertions.assertCondition(getParent() == null, "Must remove from no opt parent first");
Assertions.assertCondition(mNativeParent == null, "Must remove from native parent first");
Assertions.assertCondition(getNativeChildCount() == 0, "Must remove all native children first");
@ -806,6 +816,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void setLayoutDirection(YogaDirection direction) {
assertNotSealed();
mYogaNode.setDirection(direction);
}
@ -816,36 +827,43 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void setStyleWidth(float widthPx) {
assertNotSealed();
mYogaNode.setWidth(widthPx);
}
@Override
public void setStyleWidthPercent(float percent) {
assertNotSealed();
mYogaNode.setWidthPercent(percent);
}
@Override
public void setStyleWidthAuto() {
assertNotSealed();
mYogaNode.setWidthAuto();
}
@Override
public void setStyleMinWidth(float widthPx) {
assertNotSealed();
mYogaNode.setMinWidth(widthPx);
}
@Override
public void setStyleMinWidthPercent(float percent) {
assertNotSealed();
mYogaNode.setMinWidthPercent(percent);
}
@Override
public void setStyleMaxWidth(float widthPx) {
assertNotSealed();
mYogaNode.setMaxWidth(widthPx);
}
@Override
public void setStyleMaxWidthPercent(float percent) {
assertNotSealed();
mYogaNode.setMaxWidthPercent(percent);
}
@ -856,126 +874,151 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void setStyleHeight(float heightPx) {
assertNotSealed();
mYogaNode.setHeight(heightPx);
}
@Override
public void setStyleHeightPercent(float percent) {
assertNotSealed();
mYogaNode.setHeightPercent(percent);
}
@Override
public void setStyleHeightAuto() {
assertNotSealed();
mYogaNode.setHeightAuto();
}
@Override
public void setStyleMinHeight(float widthPx) {
assertNotSealed();
mYogaNode.setMinHeight(widthPx);
}
@Override
public void setStyleMinHeightPercent(float percent) {
assertNotSealed();
mYogaNode.setMinHeightPercent(percent);
}
@Override
public void setStyleMaxHeight(float widthPx) {
assertNotSealed();
mYogaNode.setMaxHeight(widthPx);
}
@Override
public void setStyleMaxHeightPercent(float percent) {
assertNotSealed();
mYogaNode.setMaxHeightPercent(percent);
}
@Override
public void setFlex(float flex) {
assertNotSealed();
mYogaNode.setFlex(flex);
}
@Override
public void setFlexGrow(float flexGrow) {
assertNotSealed();
mYogaNode.setFlexGrow(flexGrow);
}
@Override
public void setFlexShrink(float flexShrink) {
assertNotSealed();
mYogaNode.setFlexShrink(flexShrink);
}
@Override
public void setFlexBasis(float flexBasis) {
assertNotSealed();
mYogaNode.setFlexBasis(flexBasis);
}
@Override
public void setFlexBasisAuto() {
assertNotSealed();
mYogaNode.setFlexBasisAuto();
}
@Override
public void setFlexBasisPercent(float percent) {
assertNotSealed();
mYogaNode.setFlexBasisPercent(percent);
}
@Override
public void setStyleAspectRatio(float aspectRatio) {
assertNotSealed();
mYogaNode.setAspectRatio(aspectRatio);
}
@Override
public void setFlexDirection(YogaFlexDirection flexDirection) {
assertNotSealed();
mYogaNode.setFlexDirection(flexDirection);
}
@Override
public void setFlexWrap(YogaWrap wrap) {
assertNotSealed();
mYogaNode.setWrap(wrap);
}
@Override
public void setAlignSelf(YogaAlign alignSelf) {
assertNotSealed();
mYogaNode.setAlignSelf(alignSelf);
}
@Override
public void setAlignItems(YogaAlign alignItems) {
assertNotSealed();
mYogaNode.setAlignItems(alignItems);
}
@Override
public void setAlignContent(YogaAlign alignContent) {
assertNotSealed();
mYogaNode.setAlignContent(alignContent);
}
@Override
public void setJustifyContent(YogaJustify justifyContent) {
assertNotSealed();
mYogaNode.setJustifyContent(justifyContent);
}
@Override
public void setOverflow(YogaOverflow overflow) {
assertNotSealed();
mYogaNode.setOverflow(overflow);
}
@Override
public void setDisplay(YogaDisplay display) {
assertNotSealed();
mYogaNode.setDisplay(display);
}
@Override
public void setMargin(int spacingType, float margin) {
assertNotSealed();
mYogaNode.setMargin(YogaEdge.fromInt(spacingType), margin);
}
@Override
public void setMarginPercent(int spacingType, float percent) {
assertNotSealed();
mYogaNode.setMarginPercent(YogaEdge.fromInt(spacingType), percent);
}
@Override
public void setMarginAuto(int spacingType) {
assertNotSealed();
mYogaNode.setMarginAuto(YogaEdge.fromInt(spacingType));
}
@ -991,12 +1034,14 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void setDefaultPadding(int spacingType, float padding) {
assertNotSealed();
mDefaultPadding.set(spacingType, padding);
updatePadding();
}
@Override
public void setPadding(int spacingType, float padding) {
assertNotSealed();
mPadding[spacingType] = padding;
mPaddingIsPercent[spacingType] = false;
updatePadding();
@ -1004,12 +1049,14 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void setPaddingPercent(int spacingType, float percent) {
assertNotSealed();
mPadding[spacingType] = percent;
mPaddingIsPercent[spacingType] = !YogaConstants.isUndefined(percent);
updatePadding();
}
private void updatePadding() {
assertNotSealed();
for (int spacingType = Spacing.LEFT; spacingType <= Spacing.ALL; spacingType++) {
if (spacingType == Spacing.LEFT
|| spacingType == Spacing.RIGHT
@ -1045,36 +1092,43 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void setBorder(int spacingType, float borderWidth) {
assertNotSealed();
mYogaNode.setBorder(YogaEdge.fromInt(spacingType), borderWidth);
}
@Override
public void setPosition(int spacingType, float position) {
assertNotSealed();
mYogaNode.setPosition(YogaEdge.fromInt(spacingType), position);
}
@Override
public void setPositionPercent(int spacingType, float percent) {
assertNotSealed();
mYogaNode.setPositionPercent(YogaEdge.fromInt(spacingType), percent);
}
@Override
public void setPositionType(YogaPositionType positionType) {
assertNotSealed();
mYogaNode.setPositionType(positionType);
}
@Override
public void setShouldNotifyOnLayout(boolean shouldNotifyOnLayout) {
assertNotSealed();
mShouldNotifyOnLayout = shouldNotifyOnLayout;
}
@Override
public void setBaselineFunction(YogaBaselineFunction baselineFunction) {
assertNotSealed();
mYogaNode.setBaselineFunction(baselineFunction);
}
@Override
public void setMeasureFunction(YogaMeasureFunction measureFunction) {
assertNotSealed();
mYogaNode.setMeasureFunction(measureFunction);
}
@ -1147,6 +1201,7 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
@Override
public void setInstanceHandle(long instanceHandle) {
assertNotSealed();
mInstanceHandle = instanceHandle;
}
@ -1159,4 +1214,10 @@ public class ReactShadowNodeImpl implements ReactShadowNode<ReactShadowNodeImpl>
public boolean isSealed() {
return mIsSealed;
}
private void assertNotSealed() {
if (mIsSealed) {
throw new IllegalStateException("Can not modify sealed node " + toString());
}
}
}