예제 #1
0
 protected override void AsTextArgument(CodeWriter writer, RenderFlags flags)
 {
     if (_target != null)
     {
         _target.AsText(writer, flags);
     }
 }
        /// <summary>
        /// Write a list of CodeObjects.
        /// </summary>
        public void WriteList <T>(IEnumerable <T> enumerable, CodeObject.RenderFlags flags, CodeObject parent, int[] columnWidths) where T : CodeObject
        {
            if (enumerable == null)
            {
                return;
            }

            // Increase the indent level for any newlines that occur within the child list unless specifically told not to
            bool increaseIndent = !flags.HasFlag(CodeObject.RenderFlags.NoIncreaseIndent);

            if (increaseIndent)
            {
                BeginIndentOnNewLine(parent);
            }

            // Render the items in the list
            bool            isSingleLine = true;
            bool            isFirst      = true;
            int             column       = 0;
            IEnumerator <T> enumerator   = enumerable.GetEnumerator();
            bool            hasMore      = enumerator.MoveNext();

            while (hasMore)
            {
                CodeObject codeObject = enumerator.Current;
                hasMore = enumerator.MoveNext();
                if (codeObject != null)
                {
                    if (codeObject.IsFirstOnLine)
                    {
                        isSingleLine = false;
                        column       = 0;
                    }

                    // Render any newlines here, so that the indentation will be correct if the object has any post annotations
                    // (which are rendered separately below, so that any commas can be rendered properly).
                    if (!flags.HasFlag(CodeObject.RenderFlags.IsPrefix) && !flags.HasFlag(CodeObject.RenderFlags.SuppressNewLine) && codeObject.NewLines > 0)
                    {
                        WriteLines(codeObject.NewLines);
                        // Set the parent offset for any post annotations
                        SetParentOffset();
                    }

                    // Render the code object, omitting any EOL comments and post annotations (so they can be rendered later after
                    // any comma), and prefixing a space if it's not the first item.
                    CodeObject.RenderFlags passFlags = flags | CodeObject.RenderFlags.NoEOLComments | CodeObject.RenderFlags.NoPostAnnotations | CodeObject.RenderFlags.SuppressNewLine
                                                       | (isSingleLine ? (isFirst ? 0 : CodeObject.RenderFlags.PrefixSpace) : (codeObject.IsFirstOnLine ? 0 : CodeObject.RenderFlags.PrefixSpace));
                    codeObject.AsText(this, passFlags);
                    flags &= ~(CodeObject.RenderFlags.SuppressNewLine | CodeObject.RenderFlags.NoPreAnnotations);

                    if (hasMore)
                    {
                        // Render the trailing comma, with any EOL comments before or after it, depending on whether or not it's the last thing on the line
                        CodeObject nextObject   = enumerator.Current;
                        bool       isLastOnLine = (nextObject != null && nextObject.IsFirstOnLine);
                        if (!isLastOnLine)
                        {
                            codeObject.AsTextEOLComments(this, flags);
                        }
                        if (!flags.HasFlag(CodeObject.RenderFlags.NoItemSeparators))
                        {
                            Write(Expression.ParseTokenSeparator);
                        }
                        if (!isLastOnLine || codeObject.HasEOLComments)
                        {
                            WritePadding(codeObject, columnWidths, column);
                        }
                        if (isLastOnLine)
                        {
                            codeObject.AsTextEOLComments(this, flags);
                        }
                    }
                    else
                    {
                        if (flags.HasFlag(CodeObject.RenderFlags.HasTerminator) && !flags.HasFlag(CodeObject.RenderFlags.Description) && parent != null)
                        {
                            ((Statement)parent).AsTextTerminator(this, flags);
                        }
                        bool hasCloseBraceOnSameLine = (parent is Initializer && !((Initializer)parent).IsEndFirstOnLine);
                        if (codeObject.HasEOLComments || hasCloseBraceOnSameLine)
                        {
                            WritePadding(codeObject, columnWidths, column);

                            // If we're aligning columns and it's a multi-line list, add an extra space to line up the EOL comment
                            // or close brace since there's no trailing comma.
                            if (columnWidths != null && !isSingleLine)
                            {
                                if (_textWriter != null)
                                {
                                    _textWriter.Write(' ');
                                }
                                ++_columnNumber;
                            }
                        }
                        codeObject.AsTextEOLComments(this, flags);
                    }
                    codeObject.AsTextAnnotations(this, AnnotationFlags.IsPostfix, flags);
                }
                else if (hasMore)
                {
                    Write(Expression.ParseTokenSeparator);
                }

                isFirst = false;
                ++column;
            }

            // Reset the indent level
            if (increaseIndent)
            {
                EndIndentation(parent);
            }
        }