Ejemplo n.º 1
0
        /// <summary>
        /// Check if the open and close tags for an XML line should be on their own lines or not.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="indentlevel"></param>
        /// <returns><c>true</c> if the tags should be split, otherwise <c>false</c>.</returns>
        private bool TagsOnOwnLine(CommentLineXml line, int indentlevel)
        {
            // Check for splitting all root level tags.
            if (Settings.Default.Formatting_CommentXmlSplitAllTags && indentlevel <= 1)
            {
                return(true);
            }

            // Split if there is more than one child line.
            if (line.Lines.Count > 1)
            {
                return(true);
            }

            // Split if there is literal content (eg. a code tag).
            if (line.Content != null)
            {
                return(true);
            }

            // Split if this is a summary tag and option to split is set.
            if (Settings.Default.Formatting_CommentXmlSplitSummaryTagToMultipleLines && string.Equals(line.TagName, "summary", StringComparison.OrdinalIgnoreCase))
            {
                return(true);
            }

            // Always split on StyleCop SA1633 copyright tag.
            if (Settings.Default.Formatting_CommentXmlSplitSummaryTagToMultipleLines && string.Equals(line.TagName, "copyright", StringComparison.OrdinalIgnoreCase))
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 2
0
 public static string Format(string text, CodeCommentOptions options)
 {
     var xml = XElement.Parse(string.Format("<doc>{0}</doc>", text));
     var line = new CommentLineXml(xml, options);
     var regex = CodeCommentHelper.GetCommentRegex("CSharp", false);
     var formatter = new CommentFormatter(line, string.Empty, options, regex);
     return formatter.ToString();
 }
Ejemplo n.º 3
0
 public static string Format(string text, string prefix)
 {
     var xml = XElement.Parse($"<doc>{text}</doc>");
     var line = new CommentLineXml(xml);
     var regex = CodeCommentHelper.GetCommentRegex(CodeLanguage.CSharp, !string.IsNullOrEmpty(prefix));
     var formatter = new CommentFormatter(line, prefix, 4, regex);
     return formatter.ToString();
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Helper function to generate the preview in the options menu.
        /// </summary>
        public static string FormatXml(string text, CodeCommentOptions options)
        {
            var xml       = XElement.Parse(string.Format("<doc>{0}</doc>", text));
            var line      = new CommentLineXml(xml, options);
            var regex     = CodeCommentHelper.GetCommentRegex("CSharp", false);
            var formatter = new CommentFormatter(line, "///", options, regex);

            return(formatter.ToString());
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Helper function to generate the preview in the options menu.
        /// </summary>
        public static string FormatXml(string text)
        {
            var xml       = XElement.Parse($"<doc>{text}</doc>");
            var line      = new CommentLineXml(xml);
            var regex     = CodeCommentHelper.GetCommentRegex(CodeLanguage.CSharp, false);
            var formatter = new CommentFormatter(line, "///", 4, regex);

            return(formatter.ToString());
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Helper function to generate the preview in the options menu.
        /// </summary>
        public static string FormatXml(string text)
        {
            var xml = XElement.Parse($"<doc>{text}</doc>");
            var line = new CommentLineXml(xml);
            var regex = CodeCommentHelper.GetCommentRegex(CodeLanguage.CSharp, false);
            var formatter = new CommentFormatter(line, "///", 4, regex);

            return formatter.ToString();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Formats the comment.
        /// </summary>
        public TextPoint Format()
        {
            if (!IsValid)
            {
                throw new InvalidOperationException("Cannot format comment, the comment is not valid.");
            }

            var originalText = _startPoint.GetText(_endPoint);
            var matches      = _commentLineRegex.Matches(originalText).OfType <Match>().ToArray();

            var commentOptions = new CommentOptions
            {
                Prefix = matches.First(m => m.Success).Groups["prefix"].Value ?? string.Empty,
                Regex  = CodeCommentHelper.GetCommentRegex(_document.GetCodeLanguage(), false)
            };

            // Concatenate the comment lines without comment prefixes and see if the resulting bit
            // can be parsed as XML.
            ICommentLine line        = null;
            var          lineTexts   = matches.Select(m => m.Groups["line"].Value).ToArray();
            var          commentText = string.Join(Environment.NewLine, lineTexts);

            if (commentText.Contains('<'))
            {
                try
                {
                    var xml = XElement.Parse($"<doc>{commentText}</doc>");
                    line = new CommentLineXml(xml);
                }
                catch (System.Xml.XmlException)
                {
                    // If XML cannot be parsed, comment will be handled as a normal text comment.
                }
            }

            if (line == null)
            {
                line = new CommentLine(commentText);
            }

            var formatter = new CommentFormatter(
                line,
                _formatterOptions,
                commentOptions);

            if (!formatter.Equals(originalText))
            {
                var cursor = StartPoint.CreateEditPoint();
                cursor.Delete(EndPoint);
                cursor.Insert(formatter.ToString());
                _endPoint = cursor.CreateEditPoint();
            }

            return(EndPoint);
        }
Ejemplo n.º 8
0
        private static void AlignParamTags(CommentLineXml xml)
        {
            var paramPhrases = xml.Lines.OfType <CommentLineXml>().Where(p => string.Equals(p.TagName, "param", StringComparison.OrdinalIgnoreCase));

            if (paramPhrases.Count() > 1)
            {
                // If param tags are broken into seperate lines there is nothing to align.
                var paramSplit = paramPhrases.First().TagOptions.Split.HasFlag(XmlTagNewLine.AfterOpen);
                if (!paramSplit)
                {
                    var longestParam = paramPhrases.Max(p => p.OpenTag.Length);
                    foreach (var phrase in paramPhrases)
                    {
                        phrase.OpenTag = phrase.OpenTag.PadRight(longestParam);
                    }
                }
            }
        }
Ejemplo n.º 9
0
        /// <returns><c>true</c> if line fitted on single line, <c>false</c> if it wrapped on multiple lines.</returns>
        private bool ParseXml(CommentLineXml line, int indentLevel = 0)
        {
            // All XML lines start on a new line.
            if (!_isFirstWord)
            {
                NewLine(indentLevel);
            }

            Append(line.OpenTag);

            // If this is the StyleCop SA1633 header <copyright> tag, the content should ALWAYS be
            // indented. So if no indenting is set, fake it. This is done by adding the indenting to
            // the comment prefix, otherwise it would indent recursively.
            var isCopyrightTag = indentLevel == 0 && string.Equals(line.TagName, "copyright", StringComparison.OrdinalIgnoreCase);

            if (isCopyrightTag && Settings.Default.Formatting_CommentXmlValueIndent < 1)
            {
                _commentPrefixLength += CodeCommentHelper.CopyrightExtraIndent;
                _commentPrefix       += string.Empty.PadLeft(CodeCommentHelper.CopyrightExtraIndent);
            }

            // Increase the indent level.
            indentLevel++;

            bool tagOnOwnLine = TagsOnOwnLine(line, indentLevel);

            if (tagOnOwnLine)
            {
                NewLine(indentLevel);
            }

            // If the literal content of an XML tag is set, output that content without formatting.
            if (line.Content != null)
            {
                var codeLines = Regex.Split(line.Content.Trim('\r', '\n'), "\n");
                for (int i = 0; i < codeLines.Length; i++)
                {
                    Append(codeLines[i].TrimEnd());

                    // Append newline for all except the last line.
                    if (i + 1 < codeLines.Length)
                    {
                        NewLine(indentLevel);
                    }
                }
            }
            else
            {
                // Loop and parse all content lines, with a little hacky solution for allowing
                // the parser to know the XML tag length.
                var xmlTagLength = tagOnOwnLine ? 0 : WordLength(line.OpenTag) + WordLength(line.Closetag);
                foreach (var l in line.Lines)
                {
                    // Parse function returns true if it had to wrap lines. If so, we need to
                    // force a newline before the closing tag.
                    tagOnOwnLine |= Parse(l, indentLevel, xmlTagLength);
                }
            }

            indentLevel--;

            // Undo the indenting hack done for copyright tags.
            if (isCopyrightTag && Settings.Default.Formatting_CommentXmlValueIndent < 1)
            {
                _commentPrefixLength -= CodeCommentHelper.CopyrightExtraIndent;
                _commentPrefix        = _commentPrefix.Substring(0, _commentPrefixLength);
            }

            // If opening tag was on own line, do the same for the closing tag.
            if (tagOnOwnLine && !_isFirstWord)
            {
                NewLine(indentLevel);
            }

            Append(line.Closetag);

            return(tagOnOwnLine);
        }
Ejemplo n.º 10
0
        /// <returns>
        /// Returns <c>true</c> if the line requests a break afterwards (did not fit on a single
        /// line), otherwise <c>false</c>.
        /// </returns>
        private bool ParseXml(CommentLineXml line, int indentLevel = 0)
        {
            // All XML lines start on a new line.
            if (!_isFirstWord)
            {
                NewLine();
            }

            Indent(indentLevel);
            Append(line.OpenTag);

            // Self closing tags have no content, skip all further logic and just output.
            var tagOnOwnLine = TagsOnOwnLine(line, indentLevel);

            if (line.IsSelfClosing)
            {
                if (tagOnOwnLine)
                {
                    NewLine();
                    return(false);
                }
                return(true);
            }

            // If this is the StyleCop SA1633 header <copyright> tag, the content should ALWAYS be
            // indented. So if no indenting is set, fake it. This is done by adding the indenting to
            // the comment prefix, otherwise it would indent recursively.
            var isCopyrightTag = indentLevel == 0 && string.Equals(line.TagName, "copyright", StringComparison.OrdinalIgnoreCase);

            if (isCopyrightTag && Settings.Default.Formatting_CommentXmlValueIndent < 1)
            {
                _commentPrefixLength   += CodeCommentHelper.CopyrightExtraIndent;
                _commentOptions.Prefix += string.Empty.PadLeft(CodeCommentHelper.CopyrightExtraIndent);
            }

            // Increase the indent level.
            indentLevel++;

            var isLiteralContent = !string.IsNullOrEmpty(line.Content);

            // If true the tag should be alone on it's own line.
            tagOnOwnLine |= isLiteralContent;

            // If the literal content of an XML tag is set, output that content without formatting.
            if (isLiteralContent)
            {
                var literals = line.Content.Trim('\r', '\n').TrimEnd('\r', '\n', '\t', ' ').Split('\n');
                for (int i = 0; i < literals.Length; i++)
                {
                    NewLine(true);
                    Append(literals[i].TrimEnd());
                }
            }
            else
            {
                // If the tag has any child lines and should be on it's own line, put another break.
                if (tagOnOwnLine && line.Lines.Count > 0)
                {
                    NewLine();
                }

                // Loop and parse all content lines, with a little hacky solution for allowing the
                // parser to know the XML tag length.
                var xmlTagLength    = tagOnOwnLine ? 0 : WordLength(line.OpenTag) + WordLength(line.CloseTag);
                var needBreakBefore = false;
                foreach (var l in line.Lines)
                {
                    if (needBreakBefore)
                    {
                        NewLine();
                    }

                    // Parse function returns true if it had to wrap lines. If so, we need to force a
                    // newline before the closing tag.
                    needBreakBefore = Parse(l, indentLevel, xmlTagLength);
                    tagOnOwnLine   |= needBreakBefore;
                }
            }

            indentLevel--;

            // Undo the indenting hack done for copyright tags.
            if (isCopyrightTag && Settings.Default.Formatting_CommentXmlValueIndent < 1)
            {
                _commentPrefixLength  -= CodeCommentHelper.CopyrightExtraIndent;
                _commentOptions.Prefix = _commentOptions.Prefix.Substring(0, _commentPrefixLength);
            }

            // If opening tag was on own line, do the same for the closing tag.
            if (tagOnOwnLine && !_isFirstWord)
            {
                NewLine();
                Indent(indentLevel);
            }
            else if (Settings.Default.Formatting_CommentXmlSpaceTags)
            {
                Append(CodeCommentHelper.Spacer);
            }

            Append(line.CloseTag);

            return(tagOnOwnLine || CommentLineXml.SingleLineElementNames.Contains(line.TagName, StringComparer.OrdinalIgnoreCase));
        }
Ejemplo n.º 11
0
        /// <returns>
        /// Returns <c>true</c> if the line requests a break afterwards (did not fit on a single
        /// line), otherwise <c>false</c>.
        /// </returns>
        private bool FormatXml(CommentLineXml xml)
        {
            var isLiteralContent = !string.IsNullOrEmpty(xml.Content);
            var split            = xml.TagOptions.Split;

            if (isLiteralContent)
            {
                // Tags containing literal content with multiple with should always be on their own line.
                if (xml.Content.Contains('\n'))
                {
                    split = XmlTagNewLine.Always;
                }
            }
            else if ((split == XmlTagNewLine.Default || split == XmlTagNewLine.Content) && xml.Lines.Count > 1)
            {
                // Split always if there is more than one child line.
                split = XmlTagNewLine.Always;
            }

            if (split.HasFlag(XmlTagNewLine.BeforeOpen) && !_isFirstWord)
            {
                NewLine();
            }

            Append(xml.TagOptions.KeepTogether ? CodeCommentHelper.FakeToSpace(xml.OpenTag) : xml.OpenTag);

            // Self closing tags have no content, skip all further logic and just output.
            if (xml.IsSelfClosing)
            {
                if (split.HasFlag(XmlTagNewLine.AfterClose))
                {
                    if (!xml.IsLast)
                    {
                        NewLine();
                    }
                    return(false);
                }

                return(true);
            }

            if (split.HasFlag(XmlTagNewLine.AfterOpen))
            {
                NewLine();
            }

            // Increase the indenting.
            _indentAmount += xml.TagOptions.Indent;

            if (isLiteralContent)
            {
                // If the literal content of an XML tag is set, output that content without formatting.
                var literals = xml.Content.Trim('\r', '\n').TrimEnd('\r', '\n', '\t', ' ').Split('\n');
                for (int i = 0; i < literals.Length; i++)
                {
                    if (i > 0)
                    {
                        NewLine(true);
                    }
                    Append(literals[i].TrimEnd(), true);
                }
            }
            else
            {
                // Else output the child lines.
                var xmlTagLength = WordLength(xml.OpenTag) + WordLength(xml.CloseTag) + (xml.TagOptions.SpaceContent ? 2 : 0);

                foreach (var line in xml.Lines)
                {
                    if (!Format(line, xmlTagLength, xml.TagOptions.SpaceContent))
                    {
                        split |= XmlTagNewLine.BeforeClose | XmlTagNewLine.AfterClose;
                    }
                }
            }

            // Remove the indenting.
            _indentAmount -= xml.TagOptions.Indent;

            // If opening tag was on own line, do the same for the closing tag.
            if (split.HasFlag(XmlTagNewLine.BeforeClose))
            {
                NewLine();
            }
            else if (xml.TagOptions.SpaceContent)
            {
                Append(CodeCommentHelper.Spacer);
            }

            Append(xml.CloseTag);

            if (split.HasFlag(XmlTagNewLine.AfterClose))
            {
                //if (!xml.IsLast)
                {
                    NewLine();
                }

                return(false);
            }

            return(true);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Formats the comment.
        /// </summary>
        /// <param name="options">The options to be used for formatting.</param>
        public TextPoint Format(CodeCommentOptions options)
        {
            if (!IsValid)
            {
                throw new InvalidOperationException("Cannot format comment, the comment is not valid.");
            }

            var originalText = _startPoint.GetText(_endPoint);
            var matches = _commentLineRegex.Matches(originalText).OfType<Match>().ToArray();
            var commentPrefix = matches.First(m => m.Success).Groups["prefix"].Value;

            // Concatenate the comment lines without comment prefixes and see if the resulting bit
            // can be parsed as XML.
            ICommentLine line = null;
            var lineTexts = matches.Select(m => m.Groups["line"].Value).ToArray();
            var commentText = string.Join(Environment.NewLine, lineTexts);
            if (commentText.Contains('<'))
            {
                try
                {
                    var xml = XElement.Parse(string.Format("<doc>{0}</doc>", commentText));
                    line = new CommentLineXml(xml, options);
                }
                catch (System.Xml.XmlException)
                {
                    // If XML cannot be parsed, comment will be handled as a normal text comment.
                }
            }

            if (line == null)
            {
                line = new CommentLine(commentText);
            }

            var formatter = new CommentFormatter(
                line,
                commentPrefix,
                options,
                CodeCommentHelper.GetCommentRegex(_document.Language, false));

            if (!formatter.Equals(originalText))
            {
                var cursor = StartPoint.CreateEditPoint();
                cursor.Delete(EndPoint);
                cursor.Insert(formatter.ToString());
                _endPoint = cursor.CreateEditPoint();
            }

            return EndPoint;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Helper function to generate the preview in the options menu.
        /// </summary>
        public static string FormatXml(string text)
        {
            var xml = XElement.Parse(string.Format("<doc>{0}</doc>", text));
            var line = new CommentLineXml(xml);
            var regex = CodeCommentHelper.GetCommentRegex("CSharp", false);
            var formatter = new CommentFormatter(line, "///", 4, regex);

            return formatter.ToString();
        }