/// <summary> /// Replaces a child of this ILInstruction. /// </summary> /// <param name="childPointer">Reference to the field holding the child</param> /// <param name="newValue">New child</param> /// <param name="index">Index of the field in the Children collection</param> protected internal void SetChildInstruction(ref ILInstruction childPointer, ILInstruction newValue, int index) { ILInstruction oldValue = childPointer; Debug.Assert(oldValue == GetChild(index)); if (oldValue == newValue && newValue?.parent == this && newValue.ChildIndex == index) { return; } childPointer = newValue; if (newValue != null) { newValue.parent = this; newValue.ChildIndex = index; } InvalidateFlags(); MakeDirty(); if (refCount > 0) { // The new value may be a subtree of the old value. // We first call AddRef(), then ReleaseRef() to prevent the subtree // that stays connected from receiving a Disconnected() notification followed by a Connected() notification. if (newValue != null) { newValue.AddRef(); } if (oldValue != null) { oldValue.ReleaseRef(); } } }
/// <summary> /// Called when a new child is added to a InstructionCollection. /// </summary> protected internal void InstructionCollectionAdded(ILInstruction newChild) { Debug.Assert(GetChild(newChild.ChildIndex) == newChild); Debug.Assert(!this.IsDescendantOf(newChild), "ILAst must form a tree"); newChild.parent = this; if (refCount > 0) { newChild.AddRef(); } }
/// <summary> /// Called when a new child is added to a InstructionCollection. /// </summary> protected internal void InstructionCollectionAdded(ILInstruction newChild) { Debug.Assert(GetChild(newChild.ChildIndex) == newChild); Debug.Assert(!this.IsDescendantOf(newChild), "ILAst must form a tree"); // If a call to ReplaceWith() triggers the "ILAst must form a tree" assertion, // make sure to read the remarks on the ReplaceWith() method. newChild.parent = this; if (refCount > 0) { newChild.AddRef(); } }