CommentEmitter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataWeb / Design / system / Data / EntityModel / Emitters / CommentEmitter.cs / 1 / CommentEmitter.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.CodeDom; 
using System.Data.Common.Utils;
using System.Data.Services.Design;
using System.Data.Metadata.Edm;
using System.Diagnostics; 
using System.Globalization;
using System.Reflection; 
using System.Text.RegularExpressions; 

namespace System.Data.EntityModel.Emitters 
{
    /// 
    /// static helper class for emitting comments.
    ///  
    internal static class CommentEmitter
    { 
        #region Static Fields 
        private static readonly Regex LeadingBlanks = new Regex(@"^(?\s{1,})\S", RegexOptions.Singleline | RegexOptions.Compiled);
        #endregion 

        #region Public Methods
        /// 
        /// emit all the documentation comments for an element's documentation child 
        /// (if the element does not have a documentation child emit some standard "missing comments" comment
        ///  
        /// the element whose documenation is to be displayed 
        /// the comment collection of the CodeDom object to be commented
        public static void EmitSummaryComments(MetadataItem item, CodeCommentStatementCollection commentCollection) 
        {
            Debug.Assert(item != null, "item parameter is null");
            Debug.Assert(commentCollection != null, "commentCollection parameter is null");
 
            Documentation documentation = GetDocumentation(item);
            string [] summaryComments = null; 
            if (documentation != null && !StringUtil.IsNullOrEmptyOrWhiteSpace(documentation.Summary)) 
            {
                // we have documentation to emit 
                summaryComments = GetFormattedLines(documentation.Summary, true);
            }
            else
            { 
                string summaryComment;
                // no summary content, so use a default 
                switch (item.BuiltInTypeKind) 
                {
                    case BuiltInTypeKind.EdmProperty: 
                        summaryComment = Strings.MissingPropertyDocumentation(((EdmProperty)item).Name);
                        break;
                    case BuiltInTypeKind.ComplexType:
                        summaryComment = Strings.MissingComplexTypeDocumentation(((ComplexType)item).FullName); 
                        break;
                    default: 
                        { 
                            PropertyInfo pi = item.GetType().GetProperty("FullName");
                            if (pi == null) 
                            {
                                pi = item.GetType().GetProperty("Name");
                            }
 
                            object value = null;
                            if (pi != null) 
                            { 
                                value = pi.GetValue(item, null);
                            } 


                            if (value != null)
                            { 
                                summaryComment = Strings.MissingDocumentation(value.ToString());
                            } 
                            else 
                            {
                                summaryComment = Strings.MissingDocumentationNoName; 
                            }
                        }
                        break;
                } 
                summaryComments = new string[] { summaryComment };
            } 
            EmitSummaryComments(summaryComments, commentCollection); 
            EmitOtherDocumentationComments(documentation, commentCollection);
        } 

        private static Documentation GetDocumentation(MetadataItem item)
        {
            if (item is Documentation) 
                return (Documentation)item;
            else 
                return item.Documentation; 
        }
 
        /// 
        /// Emit summary comments from a string
        /// 
        /// the summary comments to be emitted 
        /// the comment collection of the CodeDom object to be commented
        public static void EmitSummaryComments(string summaryComments, CodeCommentStatementCollection commentCollection) 
        { 
            Debug.Assert(commentCollection != null, "commentCollection parameter is null");
 
            if (string.IsNullOrEmpty(summaryComments) || string.IsNullOrEmpty(summaryComments = summaryComments.TrimEnd()))
                return;

            EmitSummaryComments(SplitIntoLines(summaryComments), commentCollection); 
        }
 
        ///  
        /// Emit some lines of comments
        ///  
        /// the lines of comments to emit
        /// the comment collection of the CodeDom object to be commented
        /// true if the comments are 'documentation' comments
        public static void EmitComments(string[] commentLines, CodeCommentStatementCollection commentCollection, bool docComment) 
        {
            Debug.Assert(commentLines != null, "commentLines parameter is null"); 
            Debug.Assert(commentCollection != null, "commentCollection parameter is null"); 

            foreach (string comment in commentLines) 
            {
                commentCollection.Add(new CodeCommentStatement(comment, docComment));
            }
        } 

        ///  
        /// Emit documentation comments for a method parameter 
        /// 
        /// the parameter being commented 
        /// the comment text
        /// the comment collection of the CodeDom object to be commented
        public static void EmitParamComments(CodeParameterDeclarationExpression parameter, string comment,
            CodeCommentStatementCollection commentCollection) 
        {
            Debug.Assert(parameter != null, "parameter parameter is null"); 
            Debug.Assert(comment != null, "comment parameter is null"); 

            string paramComment = string.Format(System.Globalization.CultureInfo.CurrentCulture, 
                "{1}", parameter.Name, comment);
            commentCollection.Add(new CodeCommentStatement(paramComment, true));
        }
 
        /// 
        /// 'Format' a string of text into lines: separates in to lines on '\n', removes '\r', and removes common leading blanks. 
        ///  
        /// if true characters troublesome for xml are converted to entities
        /// the text to be formatted 
        /// the formatted lines
        public static string[] GetFormattedLines(string text, bool escapeForXml)
        {
#if false 
            if ( text.IndexOf("\n") >= 0 )
                Console.WriteLine("GetFormattedText(\""+text.Replace("\n","\\n").Replace("\r","\\r")+"\","+escapeForXml+")"); 
#endif 
            Debug.Assert(!string.IsNullOrEmpty(text));
 
            // nothing in, almost nothing out.
            if (StringUtil.IsNullOrEmptyOrWhiteSpace(text))
                return new string[] { "" };
 
            // normalize CRLF and LFCRs to LFs (we just remove all the crs, assuming there are no extraneous ones) and remove trailing spaces
            text = text.Replace("\r", ""); 
 
            // remove leading and.or trailing line ends to get single line for:
            //  
            // text
            // 
            bool trim = false;
            int start = text.IndexOf('\n'); 
            if (start >= 0 && StringUtil.IsNullOrEmptyOrWhiteSpace(text, 0, start + 1))
            { 
                ++start; 
                trim = true;
            } 
            else
            {
                start = 0;
            } 
            int last = text.LastIndexOf('\n');
            if (last > start - 1 && StringUtil.IsNullOrEmptyOrWhiteSpace(text, last)) 
            { 
                --last;
                trim = true; 
            }
            else
            {
                last = text.Length - 1; 
            }
            if (trim) 
            { 
                Debug.Assert(start <= last);
                text = text.Substring(start, last - start + 1); 
            }

            // break into lines (preversing blank lines and preping text for being in xml comments)
            if (escapeForXml) 
            {
                text = System.Security.SecurityElement.Escape(text); 
            } 
            string[] lines = SplitIntoLines(text);
 
            if (lines.Length == 1)
            {
                lines[0] = lines[0].Trim();
                return lines; 
            }
 
            // find the maximum leading whitespace substring (ignoring blank lines) 
            string leadingBlanks = null;
            foreach (string line in lines) 
            {
                // is an empty line
                if (StringUtil.IsNullOrEmptyOrWhiteSpace(line))
                    continue; 

                // find the leading whitespace substring 
                Match match = LeadingBlanks.Match(line); 
                if (!match.Success)
                { 
                    //none, we're done
                    leadingBlanks = "";
                    break;
                } 

                if (leadingBlanks == null) 
                { 
                    // this is first non-empty line
                    leadingBlanks = match.Groups["LeadingBlanks"].Value; 
                    continue;
                }

                // use the leadingBlanks if it matched the new one or it is a leading substring of the new one 
                string leadingBlanks2 = match.Groups["LeadingBlanks"].Value;
                if (leadingBlanks2 == leadingBlanks || leadingBlanks2.StartsWith(leadingBlanks, StringComparison.Ordinal)) 
                    continue; 

                if (leadingBlanks.StartsWith(leadingBlanks2, StringComparison.OrdinalIgnoreCase)) 
                {
                    // the current leading whitespace string is a leading substring of leadingBlanks. use the new one
                    leadingBlanks = leadingBlanks2;
                    continue; 
                }
 
                // find longest leading common substring and use that. 
                int minLength = Math.Min(leadingBlanks.Length, leadingBlanks2.Length);
                for (int j = 0; j < minLength; ++j) 
                {
                    if (leadingBlanks[j] != leadingBlanks2[j])
                    {
                        if (j == 0) 
                            leadingBlanks = "";
                        else 
                            leadingBlanks = leadingBlanks.Substring(0, j); 
                        break;
                    } 
                }

                // if we've reduced the leading substring to an empty string, we're done.
                if (string.IsNullOrEmpty(leadingBlanks)) 
                    break;
            } 
 
            // remove the leading whitespace substring and remove any trailing blanks.
            int numLeadingCharsToRemove = leadingBlanks.Length; 
            for (int i = 0; i < lines.Length; ++i)
            {
                if (lines[i].Length >= numLeadingCharsToRemove)
                    lines[i] = lines[i].Substring(numLeadingCharsToRemove); 
                lines[i] = lines[i].TrimEnd();
            } 
            return lines; 
        }
        #endregion 

        #region Private Methods
        /// 
        /// Emit the other (than Summary) documentation comments from a Documentation element 
        /// 
        /// the schema Docuementation element 
        /// the comment collection of the CodeDom object to be commented 
        private static void EmitOtherDocumentationComments(Documentation documentation, CodeCommentStatementCollection commentCollection)
        { 
            Debug.Assert(commentCollection != null);
            if (documentation == null)
                return;
 
            if (!string.IsNullOrEmpty(documentation.LongDescription))
                EmitXmlComments("LongDescription", GetFormattedLines(documentation.LongDescription, true), commentCollection); 
        } 

        ///  
        /// Emit the summary comments
        /// 
        /// 
        /// the comment collection of the CodeDom object to be commented 
        private static void EmitSummaryComments(string[] summaryComments, CodeCommentStatementCollection commentCollection)
        { 
            Debug.Assert(summaryComments != null); 
            Debug.Assert(commentCollection != null);
 
            EmitXmlComments("summary", summaryComments, commentCollection);
        }

        ///  
        /// emit documentation comments between xml open and close tags
        ///  
        /// the xml tag name 
        /// the lines of comments to emit
        /// the comment collection of the CodeDom object to be commented 
        private static void EmitXmlComments(string tag, string[] summaryComments, CodeCommentStatementCollection commentCollection)
        {
            Debug.Assert(tag != null);
            Debug.Assert(summaryComments != null); 
            Debug.Assert(commentCollection != null);
 
            commentCollection.Add(new CodeCommentStatement(string.Format(CultureInfo.InvariantCulture, "<{0}>", tag), true)); 
            EmitComments(summaryComments, commentCollection, true);
            commentCollection.Add(new CodeCommentStatement(string.Format(CultureInfo.InvariantCulture, "", tag), true)); 
        }

        /// 
        /// split a string into lines on '\n' chars and remove '\r' chars 
        /// 
        /// the string to split 
        /// the split string 
        private static string[] SplitIntoLines(string text)
        { 
            if (string.IsNullOrEmpty(text))
                return new string[] { "" };

            return text.Replace("\r", "").Split('\n'); 
        }
        #endregion 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.CodeDom; 
using System.Data.Common.Utils;
using System.Data.Services.Design;
using System.Data.Metadata.Edm;
using System.Diagnostics; 
using System.Globalization;
using System.Reflection; 
using System.Text.RegularExpressions; 

namespace System.Data.EntityModel.Emitters 
{
    /// 
    /// static helper class for emitting comments.
    ///  
    internal static class CommentEmitter
    { 
        #region Static Fields 
        private static readonly Regex LeadingBlanks = new Regex(@"^(?\s{1,})\S", RegexOptions.Singleline | RegexOptions.Compiled);
        #endregion 

        #region Public Methods
        /// 
        /// emit all the documentation comments for an element's documentation child 
        /// (if the element does not have a documentation child emit some standard "missing comments" comment
        ///  
        /// the element whose documenation is to be displayed 
        /// the comment collection of the CodeDom object to be commented
        public static void EmitSummaryComments(MetadataItem item, CodeCommentStatementCollection commentCollection) 
        {
            Debug.Assert(item != null, "item parameter is null");
            Debug.Assert(commentCollection != null, "commentCollection parameter is null");
 
            Documentation documentation = GetDocumentation(item);
            string [] summaryComments = null; 
            if (documentation != null && !StringUtil.IsNullOrEmptyOrWhiteSpace(documentation.Summary)) 
            {
                // we have documentation to emit 
                summaryComments = GetFormattedLines(documentation.Summary, true);
            }
            else
            { 
                string summaryComment;
                // no summary content, so use a default 
                switch (item.BuiltInTypeKind) 
                {
                    case BuiltInTypeKind.EdmProperty: 
                        summaryComment = Strings.MissingPropertyDocumentation(((EdmProperty)item).Name);
                        break;
                    case BuiltInTypeKind.ComplexType:
                        summaryComment = Strings.MissingComplexTypeDocumentation(((ComplexType)item).FullName); 
                        break;
                    default: 
                        { 
                            PropertyInfo pi = item.GetType().GetProperty("FullName");
                            if (pi == null) 
                            {
                                pi = item.GetType().GetProperty("Name");
                            }
 
                            object value = null;
                            if (pi != null) 
                            { 
                                value = pi.GetValue(item, null);
                            } 


                            if (value != null)
                            { 
                                summaryComment = Strings.MissingDocumentation(value.ToString());
                            } 
                            else 
                            {
                                summaryComment = Strings.MissingDocumentationNoName; 
                            }
                        }
                        break;
                } 
                summaryComments = new string[] { summaryComment };
            } 
            EmitSummaryComments(summaryComments, commentCollection); 
            EmitOtherDocumentationComments(documentation, commentCollection);
        } 

        private static Documentation GetDocumentation(MetadataItem item)
        {
            if (item is Documentation) 
                return (Documentation)item;
            else 
                return item.Documentation; 
        }
 
        /// 
        /// Emit summary comments from a string
        /// 
        /// the summary comments to be emitted 
        /// the comment collection of the CodeDom object to be commented
        public static void EmitSummaryComments(string summaryComments, CodeCommentStatementCollection commentCollection) 
        { 
            Debug.Assert(commentCollection != null, "commentCollection parameter is null");
 
            if (string.IsNullOrEmpty(summaryComments) || string.IsNullOrEmpty(summaryComments = summaryComments.TrimEnd()))
                return;

            EmitSummaryComments(SplitIntoLines(summaryComments), commentCollection); 
        }
 
        ///  
        /// Emit some lines of comments
        ///  
        /// the lines of comments to emit
        /// the comment collection of the CodeDom object to be commented
        /// true if the comments are 'documentation' comments
        public static void EmitComments(string[] commentLines, CodeCommentStatementCollection commentCollection, bool docComment) 
        {
            Debug.Assert(commentLines != null, "commentLines parameter is null"); 
            Debug.Assert(commentCollection != null, "commentCollection parameter is null"); 

            foreach (string comment in commentLines) 
            {
                commentCollection.Add(new CodeCommentStatement(comment, docComment));
            }
        } 

        ///  
        /// Emit documentation comments for a method parameter 
        /// 
        /// the parameter being commented 
        /// the comment text
        /// the comment collection of the CodeDom object to be commented
        public static void EmitParamComments(CodeParameterDeclarationExpression parameter, string comment,
            CodeCommentStatementCollection commentCollection) 
        {
            Debug.Assert(parameter != null, "parameter parameter is null"); 
            Debug.Assert(comment != null, "comment parameter is null"); 

            string paramComment = string.Format(System.Globalization.CultureInfo.CurrentCulture, 
                "{1}", parameter.Name, comment);
            commentCollection.Add(new CodeCommentStatement(paramComment, true));
        }
 
        /// 
        /// 'Format' a string of text into lines: separates in to lines on '\n', removes '\r', and removes common leading blanks. 
        ///  
        /// if true characters troublesome for xml are converted to entities
        /// the text to be formatted 
        /// the formatted lines
        public static string[] GetFormattedLines(string text, bool escapeForXml)
        {
#if false 
            if ( text.IndexOf("\n") >= 0 )
                Console.WriteLine("GetFormattedText(\""+text.Replace("\n","\\n").Replace("\r","\\r")+"\","+escapeForXml+")"); 
#endif 
            Debug.Assert(!string.IsNullOrEmpty(text));
 
            // nothing in, almost nothing out.
            if (StringUtil.IsNullOrEmptyOrWhiteSpace(text))
                return new string[] { "" };
 
            // normalize CRLF and LFCRs to LFs (we just remove all the crs, assuming there are no extraneous ones) and remove trailing spaces
            text = text.Replace("\r", ""); 
 
            // remove leading and.or trailing line ends to get single line for:
            //  
            // text
            // 
            bool trim = false;
            int start = text.IndexOf('\n'); 
            if (start >= 0 && StringUtil.IsNullOrEmptyOrWhiteSpace(text, 0, start + 1))
            { 
                ++start; 
                trim = true;
            } 
            else
            {
                start = 0;
            } 
            int last = text.LastIndexOf('\n');
            if (last > start - 1 && StringUtil.IsNullOrEmptyOrWhiteSpace(text, last)) 
            { 
                --last;
                trim = true; 
            }
            else
            {
                last = text.Length - 1; 
            }
            if (trim) 
            { 
                Debug.Assert(start <= last);
                text = text.Substring(start, last - start + 1); 
            }

            // break into lines (preversing blank lines and preping text for being in xml comments)
            if (escapeForXml) 
            {
                text = System.Security.SecurityElement.Escape(text); 
            } 
            string[] lines = SplitIntoLines(text);
 
            if (lines.Length == 1)
            {
                lines[0] = lines[0].Trim();
                return lines; 
            }
 
            // find the maximum leading whitespace substring (ignoring blank lines) 
            string leadingBlanks = null;
            foreach (string line in lines) 
            {
                // is an empty line
                if (StringUtil.IsNullOrEmptyOrWhiteSpace(line))
                    continue; 

                // find the leading whitespace substring 
                Match match = LeadingBlanks.Match(line); 
                if (!match.Success)
                { 
                    //none, we're done
                    leadingBlanks = "";
                    break;
                } 

                if (leadingBlanks == null) 
                { 
                    // this is first non-empty line
                    leadingBlanks = match.Groups["LeadingBlanks"].Value; 
                    continue;
                }

                // use the leadingBlanks if it matched the new one or it is a leading substring of the new one 
                string leadingBlanks2 = match.Groups["LeadingBlanks"].Value;
                if (leadingBlanks2 == leadingBlanks || leadingBlanks2.StartsWith(leadingBlanks, StringComparison.Ordinal)) 
                    continue; 

                if (leadingBlanks.StartsWith(leadingBlanks2, StringComparison.OrdinalIgnoreCase)) 
                {
                    // the current leading whitespace string is a leading substring of leadingBlanks. use the new one
                    leadingBlanks = leadingBlanks2;
                    continue; 
                }
 
                // find longest leading common substring and use that. 
                int minLength = Math.Min(leadingBlanks.Length, leadingBlanks2.Length);
                for (int j = 0; j < minLength; ++j) 
                {
                    if (leadingBlanks[j] != leadingBlanks2[j])
                    {
                        if (j == 0) 
                            leadingBlanks = "";
                        else 
                            leadingBlanks = leadingBlanks.Substring(0, j); 
                        break;
                    } 
                }

                // if we've reduced the leading substring to an empty string, we're done.
                if (string.IsNullOrEmpty(leadingBlanks)) 
                    break;
            } 
 
            // remove the leading whitespace substring and remove any trailing blanks.
            int numLeadingCharsToRemove = leadingBlanks.Length; 
            for (int i = 0; i < lines.Length; ++i)
            {
                if (lines[i].Length >= numLeadingCharsToRemove)
                    lines[i] = lines[i].Substring(numLeadingCharsToRemove); 
                lines[i] = lines[i].TrimEnd();
            } 
            return lines; 
        }
        #endregion 

        #region Private Methods
        /// 
        /// Emit the other (than Summary) documentation comments from a Documentation element 
        /// 
        /// the schema Docuementation element 
        /// the comment collection of the CodeDom object to be commented 
        private static void EmitOtherDocumentationComments(Documentation documentation, CodeCommentStatementCollection commentCollection)
        { 
            Debug.Assert(commentCollection != null);
            if (documentation == null)
                return;
 
            if (!string.IsNullOrEmpty(documentation.LongDescription))
                EmitXmlComments("LongDescription", GetFormattedLines(documentation.LongDescription, true), commentCollection); 
        } 

        ///  
        /// Emit the summary comments
        /// 
        /// 
        /// the comment collection of the CodeDom object to be commented 
        private static void EmitSummaryComments(string[] summaryComments, CodeCommentStatementCollection commentCollection)
        { 
            Debug.Assert(summaryComments != null); 
            Debug.Assert(commentCollection != null);
 
            EmitXmlComments("summary", summaryComments, commentCollection);
        }

        ///  
        /// emit documentation comments between xml open and close tags
        ///  
        /// the xml tag name 
        /// the lines of comments to emit
        /// the comment collection of the CodeDom object to be commented 
        private static void EmitXmlComments(string tag, string[] summaryComments, CodeCommentStatementCollection commentCollection)
        {
            Debug.Assert(tag != null);
            Debug.Assert(summaryComments != null); 
            Debug.Assert(commentCollection != null);
 
            commentCollection.Add(new CodeCommentStatement(string.Format(CultureInfo.InvariantCulture, "<{0}>", tag), true)); 
            EmitComments(summaryComments, commentCollection, true);
            commentCollection.Add(new CodeCommentStatement(string.Format(CultureInfo.InvariantCulture, "", tag), true)); 
        }

        /// 
        /// split a string into lines on '\n' chars and remove '\r' chars 
        /// 
        /// the string to split 
        /// the split string 
        private static string[] SplitIntoLines(string text)
        { 
            if (string.IsNullOrEmpty(text))
                return new string[] { "" };

            return text.Replace("\r", "").Split('\n'); 
        }
        #endregion 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK