private IEnumerable <UtokenBase> YieldIndentationRight(UnparsableAst self, ref BlockIndentation blockIndentation) { Unparser.tsUnparse.Debug("YieldIndentationRight"); try { // NOTE: topAncestorCacheForLeft may get updated by YieldIndentation // NOTE: ToList is needed to fully evaluate the called function, so we can catch the exception return(_YieldIndentation(self, ref blockIndentation, direction, formatYielder: this, left: false).ToList()); } catch (NonCalculatedException) { // top left node or someone in the chain is non-calculated -> defer execution Debug.Assert(blockIndentation == BlockIndentation.ToBeSet || blockIndentation.IsDeferred()); if (blockIndentation == BlockIndentation.ToBeSet) { blockIndentation = BlockIndentation.Defer(); } Debug.Assert(blockIndentation.IsDeferred()); BlockIndentation _blockIndentation = blockIndentation; return(new[] { blockIndentation.RightDeferred = new DeferredUtokens( () => _YieldIndentation(self, _blockIndentation, direction, formatYielder: this, left: false), self: self, helpMessage: "YieldIndentationRight", helpCalculatedObject: _blockIndentation ) }); } }
/// <exception cref="UnparsableAst.NonCalculatedException"> /// If topLeft is non-calculated or thrown out. /// </exception> private static IEnumerable <UtokenBase> _YieldIndentation(UnparsableAst self, ref BlockIndentation blockIndentationParameter, Unparser.Direction direction, FormatYielder formatYielder, bool left) { if (!left && direction == Unparser.Direction.RightToLeft && blockIndentationParameter.IsDeferred() && blockIndentationParameter.LeftDeferred != null) { /* * We are in a right-to-left unparse and this deferred right indentation depends on a deferred left indentation, * so let's try to calculate the deferred left indentation, which - if succeed - will change the shared blockIndentation * object state from deferred to a valid indentation. * * (If the left indentation wasn't deferred then it would be calculated which means that the shared blockIndentation * object won't be deferred.) * */ blockIndentationParameter.LeftDeferred.CalculateUtokens(); // either CalculateUtokens succeeded, and blockIndentation is not deferred, or CalculateUtokens threw a NonCalculatedException exception Debug.Assert(!blockIndentationParameter.IsDeferred(), "CalculateUtokens succeeded, but blockIndentation remained deferred"); } if (blockIndentationParameter == BlockIndentation.ToBeSet || blockIndentationParameter.IsDeferred()) { UnparsableAst leftObject = GetLeftTerminalLeave(self); BlockIndentation blockIndentation = formatYielder._GetBlockIndentation(leftObject, self); // NOTE: topAncestorCacheForLeft gets updated by GetUsedLeftsFromTopToBottomB if (blockIndentation != BlockIndentation.IndentNotNeeded) { Unparser.tsUnparse.Debug("blockindentation {0} for leftTarget '{1}' and for target '{2}'", blockIndentation, leftObject, self); } Debug.Assert(!blockIndentation.IsDeferred()); if (blockIndentationParameter == BlockIndentation.ToBeSet) { blockIndentationParameter = blockIndentation; } else { blockIndentationParameter.CopyKindFrom(blockIndentation); } } if (direction == Unparser.Direction.LeftToRight) { return(left ? BlockIndentationToUtokenControlBefore(blockIndentationParameter) : BlockIndentationToUtokenControlAfter(blockIndentationParameter)); } else { return(left ? BlockIndentationToUtokenControlAfter(blockIndentationParameter) : BlockIndentationToUtokenControlBefore(blockIndentationParameter)); } }
private IEnumerable <UtokenBase> YieldIndentationRight(UnparsableAst self, BlockIndentation blockIndentation) { #if DEBUG BlockIndentation originalBlockIndentation = blockIndentation; #endif var utokens = YieldIndentationRight(self, ref blockIndentation); #if DEBUG Debug.Assert(object.ReferenceEquals(blockIndentation, originalBlockIndentation), "unwanted change of blockIndentationParameter reference in YieldIndentationRight"); #endif return(utokens); }
/// <summary> /// This method needs to be fully executed before UnparseRawMiddle because this method modifies the state of Unparser and, /// which state is used by UnparseRawMiddle. Thus, always call this method prior to UnparseRawMiddle. /// </summary> internal IEnumerable <UtokenBase> YieldBefore(UnparsableAst self, out Params @params) { /* * To achieve fully execution before UnparseRawMiddle, this method is not an iterator block rather populates a list. * Returning IReadOnlyList instead of IEnumerable is just an explicit guarantee to the caller to ensure that * the returned utokens does not need to be iterated through e.g. by converting it to a list in order to achieve full execution. * */ Unparser.tsUnparse.Debug("YieldBefore"); UpdateCacheOnTheFly(self, State.Before); var utokens = new List <UtokenBase>(); BlockIndentation blockIndentation = BlockIndentation.ToBeSet; if (direction == Unparser.Direction.LeftToRight) { utokens.AddRange(YieldBetween(self)); utokens.AddRange(YieldIndentationLeft(self, ref blockIndentation)); } else { utokens.AddRange(YieldIndentationRight(self, ref blockIndentation)); } InsertedUtokens leftInsertedUtokens; InsertedUtokens rightInsertedUtokens; _GetUtokensAround(self, out leftInsertedUtokens, out rightInsertedUtokens); InsertedUtokens insertedUtokensBefore; InsertedUtokens insertedUtokensAfter; if (direction == Unparser.Direction.LeftToRight) { insertedUtokensBefore = leftInsertedUtokens; insertedUtokensAfter = rightInsertedUtokens; } else { insertedUtokensBefore = rightInsertedUtokens; insertedUtokensAfter = leftInsertedUtokens; } if (insertedUtokensBefore != InsertedUtokens.None) { Unparser.tsUnparse.Debug("inserted utokens: {0}", insertedUtokensBefore); utokens.Add(insertedUtokensBefore); } @params = new Params(blockIndentation, insertedUtokensAfter); return(utokens); }
/// <exception cref="UnparsableAst.NonCalculatedException"> /// If topLeft is non-calculated or thrown out. /// </exception> private static IEnumerable <UtokenBase> _YieldIndentation(UnparsableAst self, BlockIndentation blockIndentationParameter, Unparser.Direction direction, FormatYielder formatYielder, bool left) { #if DEBUG BlockIndentation originalBlockIndentationParameter = blockIndentationParameter; #endif var utokens = _YieldIndentation(self, ref blockIndentationParameter, direction, formatYielder, left); #if DEBUG Debug.Assert(object.ReferenceEquals(blockIndentationParameter, originalBlockIndentationParameter), string.Format("unwanted change of blockIndentationParameter reference in _YieldIndentation ({0})", left ? "left" : "right")); #endif return(utokens); }
internal IEnumerable <UtokenBase> YieldAfter(UnparsableAst self, Params @params) { Unparser.tsUnparse.Debug("YieldAfter"); InsertedUtokens insertedUtokensAfter = @params.insertedUtokensAfter; if (insertedUtokensAfter != InsertedUtokens.None) { Unparser.tsUnparse.Debug("inserted utokens: {0}", insertedUtokensAfter); yield return(insertedUtokensAfter); } BlockIndentation blockIndentation = @params.blockIndentation; if (direction == Unparser.Direction.LeftToRight) { foreach (UtokenBase utoken in YieldIndentationRight(self, blockIndentation)) { yield return(utoken); } } else { foreach (UtokenBase utoken in YieldIndentationLeft(self, blockIndentation)) { yield return(utoken); } foreach (UtokenBase utoken in YieldBetween(self)) { yield return(utoken); } } UpdateCacheOnTheFly(self, State.After); }
public Params(BlockIndentation blockIndentation, InsertedUtokens insertedUtokensAfter) { this.blockIndentation = blockIndentation; this.insertedUtokensAfter = insertedUtokensAfter; }
private static IEnumerable <UtokenControl> BlockIndentationToUtokenControlAfter(BlockIndentation blockIndentation) { if (blockIndentation == BlockIndentation.Indent) { yield return(UtokenControl.DecreaseIndentLevel); } else if (blockIndentation == BlockIndentation.Unindent) { yield return(UtokenControl.IncreaseIndentLevel); } else if (blockIndentation == BlockIndentation.ZeroIndent) { yield return(UtokenControl.RestoreIndentLevel); } }
private static IEnumerable <UtokenControl> BlockIndentationToUtokenControlBefore(BlockIndentation blockIndentation) { if (blockIndentation == BlockIndentation.Indent) { yield return(UtokenControl.IncreaseIndentLevel); } else if (blockIndentation == BlockIndentation.Unindent) { yield return(UtokenControl.DecreaseIndentLevel); } else if (blockIndentation == BlockIndentation.ZeroIndent) { yield return(UtokenControl.SetIndentLevelToNone); } }