/// <summary> /// The left represents a tree of L-values. The structure of right can be missing parts of the tree on the left. /// The conversion holds nested conversions and deconstruction information, which matches the tree from the left, /// and it provides the information to fill in the missing parts of the tree from the right and convert it to /// the tree from the left. /// /// A bound sequence is returned which has different phases of side-effects: /// - the initialization phase includes side-effects from the left, followed by evaluations of the right /// - the deconstruction phase includes all the invocations of Deconstruct methods and tuple element accesses below a Deconstruct call /// - the conversion phase /// - the assignment phase /// </summary> private BoundExpression RewriteDeconstruction(BoundTupleExpression left, Conversion conversion, BoundExpression right, bool isUsed) { var lhsTemps = ArrayBuilder <LocalSymbol> .GetInstance(); var lhsEffects = ArrayBuilder <BoundExpression> .GetInstance(); ArrayBuilder <Binder.DeconstructionVariable> lhsTargets = GetAssignmentTargetsAndSideEffects(left, lhsTemps, lhsEffects); BoundExpression result = RewriteDeconstruction(lhsTargets, conversion, left.Type, right, isUsed); Binder.DeconstructionVariable.FreeDeconstructionVariables(lhsTargets); if (result is null) { lhsTemps.Free(); lhsEffects.Free(); return(null); } return(_factory.Sequence(lhsTemps.ToImmutableAndFree(), lhsEffects.ToImmutableAndFree(), result)); }
/// <summary> /// Converts the expression for creating a tuple instance into an expression creating a ValueTuple (if short) or nested ValueTuples (if longer). /// /// For instance, for a long tuple we'll generate: /// creationExpression(ctor=largestCtor, args=firstArgs+(nested creationExpression for remainder, with smaller ctor and next few args)) /// </summary> private BoundExpression RewriteTupleCreationExpression(BoundTupleExpression node, ImmutableArray <BoundExpression> rewrittenArguments) { return(MakeTupleCreationExpression(node.Syntax, (NamedTypeSymbol)node.Type, rewrittenArguments)); }
private BoundNode VisitTupleExpression(BoundTupleExpression node) { ImmutableArray <BoundExpression> rewrittenArguments = VisitList(node.Arguments); return(RewriteTupleCreationExpression(node, rewrittenArguments)); }