public override void AsText(CodeWriter writer, RenderFlags flags)
        {
            int  newLines = NewLines;
            bool isPrefix = flags.HasFlag(RenderFlags.IsPrefix);

            if (!isPrefix && newLines > 0)
            {
                if (!flags.HasFlag(RenderFlags.SuppressNewLine))
                {
                    writer.WriteLines(newLines);
                }
            }
            else if (flags.HasFlag(RenderFlags.PrefixSpace))
            {
                writer.Write(" ");
            }

            RenderFlags passFlags = (flags & RenderFlags.PassMask);

            AsTextBefore(writer, passFlags | RenderFlags.IsPrefix);
            UpdateLineCol(writer, flags);
            writer.Write(ParseTokenStart);

            // Increase the indent level for any newlines that occur within the declaration if the flag is set
            bool increaseIndent = flags.HasFlag(RenderFlags.IncreaseIndent);

            if (increaseIndent)
            {
                writer.BeginIndentOnNewLine(this);
            }

            if (_target != AttributeTarget.None)
            {
                writer.Write(AttributeTargetHelpers.AsString(_target) + ParseTokenTarget + " ");
            }
            writer.WriteList(_attributeExpressions, passFlags | RenderFlags.Attribute, this);

            if (increaseIndent)
            {
                writer.EndIndentation(this);
            }

            writer.Write(ParseTokenEnd);
            AsTextEOLComments(writer, flags);
            AsTextAfter(writer, passFlags | (flags & RenderFlags.NoPostAnnotations));

            if (isPrefix)
            {
                // If this object is rendered as a child prefix object of another, then any whitespace is
                // rendered here *after* the object instead of before it.
                if (newLines > 0)
                {
                    writer.WriteLines(newLines);
                }
                else
                {
                    writer.Write(" ");
                }
            }
        }
        protected static void AsTextAttributes(CodeWriter writer, IList <CustomAttributeData> attributes, AttributeTarget attributeTarget)
        {
            int count = 0;

            foreach (CustomAttributeData attribute in attributes)
            {
                Type declaringType = attribute.Constructor.DeclaringType;
                if (declaringType != null)
                {
                    string name = declaringType.Name;
                    if (count > 0)
                    {
                        writer.Write(" ");
                    }
                    writer.Write(ParseTokenStart);
                    if (attributeTarget != AttributeTarget.None)
                    {
                        writer.Write(AttributeTargetHelpers.AsString(attributeTarget) + ": ");
                    }
                    if (name.EndsWith(NameSuffix))
                    {
                        name = name.Substring(0, name.Length - NameSuffix.Length);
                    }
                    writer.Write(name);

                    if (attribute.ConstructorArguments.Count > 0)
                    {
                        writer.Write(ParameterDecl.ParseTokenStart);
                        foreach (CustomAttributeTypedArgument argument in attribute.ConstructorArguments)
                        {
                            AsTextValue(writer, argument.Value);
                        }
                        writer.Write(ParameterDecl.ParseTokenEnd);
                    }
                    else if (attribute.NamedArguments != null && attribute.NamedArguments.Count > 0)
                    {
                        writer.Write(ParameterDecl.ParseTokenStart);
                        foreach (CustomAttributeNamedArgument argument in attribute.NamedArguments)
                        {
                            writer.Write(argument.MemberInfo.Name + " = ");
                            AsTextValue(writer, argument.TypedValue.Value);
                        }
                        writer.Write(ParameterDecl.ParseTokenEnd);
                    }

                    writer.Write(ParseTokenEnd);
                    ++count;
                }
            }
            if (count > 0)
            {
                writer.WriteLine();
            }
        }
        protected Attribute(Parser parser, CodeObject parent)
            : base(parser, parent)
        {
            parser.NextToken();  // Move past '['

            if (parser.PeekNextTokenText() == ParseTokenTarget)
            {
                _target = AttributeTargetHelpers.Parse(parser);
            }

            // Parse attribute expressions (will parse to a Call if parens are used, otherwise a ConstructorRef)
            _attributeExpressions = Expression.ParseList(parser, this, ParseTokenEnd);

            ParseExpectedToken(parser, ParseTokenEnd);  // Move past ']'
        }