/// <summary> /// Reduces this node to a simpler expression. If CanReduce returns /// true, this should return a valid expression. This method is /// allowed to return another node which itself must be reduced. /// </summary> /// <returns>The reduced expression.</returns> /// <remarks > /// Unlike Reduce, this method checks that the reduced node satisfies /// certain invariants. /// </remarks> public Expression ReduceAndCheck() { if (!CanReduce) { throw Error.MustBeReducible(); } Expression newNode = Reduce(); // 1. Reduction must return a new, non-null node // 2. Reduction must return a new node whose result type can be assigned to the type of the original node if (newNode == null || newNode == this) { throw Error.MustReduceToDifferent(); } if (!TypeUtils.AreReferenceAssignable(Type, newNode.Type)) { throw Error.ReducedNotCompatible(); } return(newNode); }