예제 #1
0
        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
                        )
                });
            }
        }
예제 #2
0
        /// <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));
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
        }
예제 #7
0
 public Params(BlockIndentation blockIndentation, InsertedUtokens insertedUtokensAfter)
 {
     this.blockIndentation     = blockIndentation;
     this.insertedUtokensAfter = insertedUtokensAfter;
 }
예제 #8
0
        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);
            }
        }
예제 #9
0
        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);
            }
        }