/// <summary>
        /// Our internal implementation of the bulb item which assumes it is running within a transaction
        /// </summary>
        /// <param name="solution">The currently open solution</param>
        /// <param name="textControl">The text control that is currently open</param>
        public void ExecuteEx(ISolution solution, ITextControl textControl)
        {
            // Get the comment block owner (ie the part of the declaration which will own the comment).
            IDocCommentBlockOwner docCommentBlockOwnerNode =
                XmlDocTemplateUtil.FindDocCommentOwner(_declaration as ITypeMemberDeclaration);

            // If we didn't get an owner then give up
            if (docCommentBlockOwnerNode == null)
            {
                return;
            }

            // We got one

            // Ask resharper to create the xml for us.
            int    myCursorOffset;
            string text = XmlDocTemplateUtil.GetDocTemplate(docCommentBlockOwnerNode, out myCursorOffset);

            // Get a factory which can create elements in the C# docs
            CSharpElementFactory factory = CSharpElementFactory.GetInstance(docCommentBlockOwnerNode.GetPsiModule());

            // Create the comment block
            IDocCommentBlock comment = factory.CreateDocCommentBlock(text);

            // And set the comment on the declaration.
            docCommentBlockOwnerNode.SetDocCommentBlock(comment);
        }
Пример #2
0
        /// <summary>
        /// Creates a new DeclarationHeader for the declaration and assigns it to the declaration.
        /// </summary>
        /// <param name="declaration">
        /// The declaration to create the header for.
        /// </param>
        /// <param name="docConfig">
        /// Provides the configuration for the current ProjectFile.
        /// </param>
        /// <returns>
        /// A DeclarationHeader for the declaration passed in.
        /// </returns>
        public static DeclarationHeader CreateNewHeader(IDeclaration declaration, DocumentationRulesConfiguration docConfig)
        {
            IFile file = declaration.GetContainingFile();

            using (WriteLockCookie.Create(file.IsPhysical()))
            {
                IDeclaration declarationTreeNode = declaration;

                IContextBoundSettingsStore settingsStore = PsiSourceFileExtensions.GetSettingsStore(null, declaration.GetSolution());
                bool   useSingleLineDeclarationComments  = settingsStore.GetValue((StyleCopOptionsSettingsKey key) => key.UseSingleLineDeclarationComments);
                string middleText = useSingleLineDeclarationComments ? string.Empty : Environment.NewLine;

                string emptyDocHeader = string.Format("<summary>{0}</summary>", middleText);

                if (!(declarationTreeNode is IMultipleDeclarationMember))
                {
                    emptyDocHeader = CreateDocumentationForElement((IDocCommentBlockOwner)declaration, docConfig);
                    emptyDocHeader = emptyDocHeader.Substring(0, emptyDocHeader.Length - Environment.NewLine.Length);
                }

                string header = LayoutDocumentationHeader(emptyDocHeader, declaration);

                IDocCommentBlock newDocCommentNode = Utils.CreateDocCommentBlockNode(file, header);

                IDocCommentBlockOwner docCommentBlockOwnerNode = Utils.GetDocCommentBlockOwnerNodeForDeclaration(declaration);

                if (docCommentBlockOwnerNode != null)
                {
                    docCommentBlockOwnerNode.SetDocCommentBlock(newDocCommentNode);
                }

                return(new DeclarationHeader(declaration));
            }
        }
Пример #3
0
        public void Process(IDocCommentBlock docCommentBlockNode)
        {
            if (IsValid() == false)
            {
                return;
            }

            AnalyzeUnit.DocumentationBlock = new DocCommentBlockModel(AnalyzeUnit, docCommentBlockNode);
        }
        /// <summary>
        /// Reflow the given comment block to fit within the given maximum line length
        /// </summary>
        /// <param name="blockNode">The comment block to reflow</param>
        /// <param name="maxLineLength">The maximum line length</param>
        /// <returns>The text for the new reflown comment.</returns>
        public string ReflowAndRetag(IDocCommentBlock blockNode, int maxLineLength)
        {
            ITreeNode parent = blockNode.Parent;
            ICSharpTypeMemberDeclaration parentDeclaration = parent as IClassMemberDeclaration;

            if (parentDeclaration == null)
            {
                IMultipleFieldDeclaration multipleFieldDeclaration = parent as IMultipleFieldDeclaration;
                if (multipleFieldDeclaration != null)
                {
                    foreach (IFieldDeclaration field in multipleFieldDeclaration.Children <IFieldDeclaration>())
                    {
                        parentDeclaration = field;
                        break;
                    }
                }

                IEnumMemberDeclaration enumMemberDeclaration = parent as IEnumMemberDeclaration;
                if (enumMemberDeclaration != null)
                {
                    parentDeclaration = enumMemberDeclaration;
                }
            }

            // get the xml from the comment
            XmlNode node = blockNode.GetXML(null);

            // Walk the xml tree and process elements as we go. Use a recursive algo for now - comments shouldn't be that complex.
            XmlCommentOptions options = new XmlCommentOptions();

            options.Declaration           = parentDeclaration;
            options.IdentifierLookupScope = IdentifierLookupScopes.ProjectAndUsings;
            options.Solution = blockNode.GetSolution();

            List <Regex> ignoreList = new List <Regex>(_settings.CompiledWordsToIgnoreForMetatagging);

            ignoreList.Add(new Regex("^[Aa]$"));
            ignoreList.Add(new Regex("^[iI]f$"));
            ignoreList.Add(new Regex("^[tT]his$"));
            ignoreList.Add(new Regex("^[eE]lse$"));
            ignoreList.Add(new Regex("^[lL]ong$"));
            ignoreList.Add(new Regex("^[wW]hile$"));
            ignoreList.Add(new Regex("^[lL]ock$"));
            ignoreList.Add(new Regex("^[fF]ixed$"));
            ignoreList.Add(new Regex("^[bB]ase$"));
            ignoreList.Add(new Regex("^[oO]bject$"));

            options.IdentifiersToIgnoreForMetaTagging = ignoreList;

            options.Settings = _reflowSettings;

            XmlComments.XmlComment comment = new XmlComments.XmlComment(options);
            comment.FromXml(node);
            comment.InsertMissingTags();
            return(comment.ToXml(0, maxLineLength, 0));
        }
Пример #5
0
        private IEnumerable <Range> GetWordsFromXmlComment(IDocCommentBlock docBlock)
        {
            if (docBlock != null)
            {
                XmlDocLexer lexer = new XmlDocLexer(docBlock);
                lexer.Start();
                int inCode = 0;
                while (lexer.TokenType != null)
                {
                    if (lexer.TokenType == lexer.XmlTokenType.TAG_START)
                    {
                        lexer.Advance();
                        if (lexer.TokenType == lexer.XmlTokenType.IDENTIFIER &&
                            (lexer.TokenText == "code" || lexer.TokenText == "c"))
                        {
                            inCode++;
                        }

                        while (lexer.TokenType != lexer.XmlTokenType.TAG_END &&
                               lexer.TokenType != lexer.XmlTokenType.TAG_END1 &&
                               lexer.TokenType != null)
                        {
                            lexer.Advance();
                        }

                        if (lexer.TokenType == lexer.XmlTokenType.TAG_END1)
                        {
                            inCode--;
                        }
                    }
                    if (lexer.TokenType == lexer.XmlTokenType.TAG_START1)
                    {
                        lexer.Advance();
                        if (lexer.TokenType == lexer.XmlTokenType.IDENTIFIER &&
                            (lexer.TokenText == "code" || lexer.TokenText == "c"))
                        {
                            inCode--;
                        }
                    }
                    if (lexer.TokenType == lexer.XmlTokenType.TEXT && inCode == 0)
                    {
                        ILexer wordLexer = new WordLexer(lexer.TokenText);
                        wordLexer.Start();
                        while (wordLexer.TokenType != null)
                        {
                            int start = lexer.CurrentNode.GetTreeStartOffset().Offset + lexer.TokenStart + wordLexer.TokenStart;
                            int end   = start + wordLexer.GetCurrTokenText().Length;
                            yield return(new Range(wordLexer.GetCurrTokenText(), new TreeTextRange(new TreeOffset(start), new TreeOffset(end))));

                            wordLexer.Advance();
                        }
                    }
                    lexer.Advance();
                }
            }
        }
Пример #6
0
        private static bool ShallEscape(IDocCommentNode node, int offset)
        {
            IDocCommentBlock docBlock = node.GetContainingNode <IDocCommentBlock>(true);

            if (docBlock == null)
            {
                return(false);
            }
            XmlDocLexer lexer = new XmlDocLexer(docBlock);

            lexer.Start();

            bool inCData   = false;
            bool insideTag = false;

            while (lexer.TokenType != null)
            {
                if (lexer.TokenType == lexer.XmlTokenType.TAG_START)
                {
                    insideTag = true;
                }
                else if (lexer.TokenType == lexer.XmlTokenType.TAG_END)
                {
                    insideTag = false;
                }
                else if (lexer.TokenType == lexer.XmlTokenType.TAG_START1)
                {
                    insideTag = true;
                }
                else if (lexer.TokenType == lexer.XmlTokenType.TAG_END1)
                {
                    insideTag = false;
                }
                else if (lexer.TokenType == lexer.XmlTokenType.CDATA_START)
                {
                    inCData = true;
                }
                else if (lexer.TokenType == lexer.XmlTokenType.CDATA_END)
                {
                    inCData = false;
                }
                else if (offset >= lexer.TokenLocalRange.StartOffset && offset <= lexer.TokenLocalRange.EndOffset)
                {
                    return(!inCData && !insideTag);
                }
                else if (offset < lexer.TokenLocalRange.StartOffset)
                {
                    return(false);
                }
                lexer.Advance();
            }

            return(false);
        }
        public IEnumerable <Paragraph> Parse(IDocCommentBlock blockNode)
        {
            // Create a lexer which can read the comment
            XmlCommentReflowableBlockLexer lexer = new XmlCommentReflowableBlockLexer(blockNode);

            // Create a parser which can turn the comment into paragraphs and lines
            XmlCommentParagraphParser paragraphParser = new XmlCommentParagraphParser(lexer);

            // Firstly walk through the paragraphs and:
            // - collapse each one to the minimum number of required lines (tags always take a whole line at this stage).
            // - remove extra whitespace. There's no point in having it, it wont show in generated doco
            return(paragraphParser.Parse());
        }
Пример #8
0
        public static void ReFlowCommentNode(ISolution solution, IProgressIndicator progress, [NotNull] IDocCommentNode docCommentNode)
        {
            // Get the comment block owner (ie the part of the declaration which will own the comment).
            IDocCommentBlock blockNode =
                docCommentNode.GetContainingNode <IDocCommentBlock>();

            if (blockNode == null)
            {
                return;
            }

            ReFlowCommentBlockNode(solution, progress, blockNode);
        }
Пример #9
0
        /// <summary>
        /// The execute transaction inner.
        /// </summary>
        /// <param name="solution">
        /// The solution.
        /// </param>
        /// <param name="textControl">
        /// The text control.
        /// </param>
        public override void ExecuteTransactionInner(ISolution solution, ITextControl textControl)
        {
            ITreeNode element = Utils.GetElementAtCaret(solution, textControl);

            ITreeNode currentNode = element;

            IDocCommentNode docCommentNode = currentNode as IDocCommentNode;

            IDocCommentBlock containingElement = docCommentNode.GetContainingNode <IDocCommentBlock>(true);

            ITreeNode rightNode = containingElement.FindFormattingRangeToRight();

            Utils.RemoveNewLineBefore(rightNode);
        }
        public static void ReflowAndRetagCommentBlockNode(ISolution solution, IProgressIndicator progress, IDocCommentBlock docCommentBlockNode)
        {
            if (docCommentBlockNode == null)
            {
                return;
            }

            // Get the settings.
            IContextBoundSettingsStore settingsStore = Shell.Instance.GetComponent <ISettingsStore>().BindToContextTransient(ContextRange.ApplicationWide);
            XmlDocumentationSettings   settings      =
                settingsStore.GetKey <XmlDocumentationSettings>(SettingsOptimization.OptimizeDefault);
            ReflowAndRetagSettings reflowSettings =
                settingsStore.GetKey <ReflowAndRetagSettings>(SettingsOptimization.OptimizeDefault);
            int maxLength = settings.MaxCharactersPerLine;

            // Get the comment block owner (ie the part of the declaration which will own the comment).
            IDocCommentBlockOwner ownerNode =
                docCommentBlockNode.GetContainingNode <IDocCommentBlockOwner>();

            // If we didn't get an owner then give up
            if (ownerNode == null)
            {
                return;
            }

            // Get a factory which can create elements in the C# docs
            //CSharpElementFactory factory = CSharpElementFactory.GetInstance(ownerNode.GetPsiModule());

            // Calculate line offset where /// starts and add 4 for the slashes and space
            int startPos = CalcLineOffset(ownerNode) + 4;

            // Create a new comment block with the adjusted text
            IDocCommentBlock comment = docCommentBlockNode; //factory.CreateDocCommentBlock(text);

            string reflownText = new XmlCommentReflower(settings, reflowSettings).ReflowAndRetag(comment, maxLength - startPos);

            // If the xml was malformed then the comment will now be empty - detect this and do nothing
            if (string.IsNullOrEmpty(reflownText))
            {
                return;
            }

            /*comment = factory.CreateDocCommentBlock(reflownText);
             *
             * // And set the comment on the declaration.
             * ownerNode.SetDocCommentBlockNode(comment);*/

            SetDocComment(ownerNode, reflownText, solution);
        }
        public static void ReflowAndRetagCommentNode(ISolution solution, IProgressIndicator progress, IDocCommentNode docCommentNode)
        {
            if (docCommentNode == null)
            {
                return;
            }

            IDocCommentBlock blockNode =
                docCommentNode.GetContainingNode <IDocCommentBlock>();

            if (blockNode == null)
            {
                return;
            }

            ReflowAndRetagCommentBlockNode(solution, progress, blockNode);
        }
Пример #12
0
        public static void ReFlowCommentBlockNode(ISolution solution, IProgressIndicator progress, IDocCommentBlock docCommentBlockNode)
        {
            if (docCommentBlockNode == null)
            {
                return;
            }

            // Get the settings.
            IContextBoundSettingsStore settingsStore = Shell.Instance.GetComponent <ISettingsStore>().BindToContextTransient(ContextRange.ApplicationWide);
            XmlDocumentationSettings   settings      =
                settingsStore.GetKey <XmlDocumentationSettings>(SettingsOptimization.OptimizeDefault);
            ReflowAndRetagSettings reflowSettings =
                settingsStore.GetKey <ReflowAndRetagSettings>(SettingsOptimization.OptimizeDefault);
            int maxLength = settings.MaxCharactersPerLine;

            IDocCommentBlockOwner ownerNode =
                docCommentBlockNode.GetContainingNode <IDocCommentBlockOwner>();

            // If we didn't get an owner then give up
            if (ownerNode == null)
            {
                return;
            }

            // Get a factory which can create elements in the C# docs
            //CSharpElementFactory factory = CSharpElementFactory.GetInstance(ownerNode.GetPsiModule());

            // Calculate line offset where /// starts and add 3 for each
            // slash.
            int startPos = CalcLineOffset(ownerNode) + 3;

            // Create a new comment block with the adjusted text
            IDocCommentBlock comment = docCommentBlockNode; //factory.CreateDocCommentBlock(text);

            // Work out if we have a space between the /// and <summary>
            string reflownText = new XmlCommentReflower(settings, reflowSettings).Reflow(comment, maxLength - startPos);

            //comment = factory.CreateDocCommentBlock(reflownText);

            SetDocComment(ownerNode, reflownText, solution);

            // And set the comment on the declaration.
            //ownerNode.SetDocCommentBlockNode(comment);
        }
Пример #13
0
        /// <summary>
        /// Updates the elements header with the current xml.
        /// </summary>
        public void Update()
        {
            if (this.DocCommentBlockNode != null)
            {
                IFile file = this.Declaration.GetContainingFile();

                using (this.DocCommentBlockNode.CreateWriteLock())
                {
                    string           header            = LayoutDocumentationHeader(this.XmlNode, this.Declaration);
                    IDocCommentBlock newDocCommentNode = Utils.CreateDocCommentBlockNode(file, header);

                    if (newDocCommentNode == null)
                    {
                        ModificationUtil.DeleteChild(this.DocCommentBlockNode);
                    }
                    else
                    {
                        ModificationUtil.ReplaceChild(this.DocCommentBlockNode, newDocCommentNode);
                    }
                }
            }
        }
Пример #14
0
        public void CheckCommentSpelling(IClassMemberDeclaration decl, [CanBeNull] IDocCommentBlock docNode,
                                         DefaultHighlightingConsumer consumer, bool spellCheck)
        {
            if (docNode == null)
            {
                return;
            }

            IFile file = decl.GetContainingFile();

            if (file == null)
            {
                return;
            }

            foreach (Range wordRange in this.GetWordsFromXmlComment(docNode))
            {
                DocumentRange range = file.GetDocumentRange(wordRange.TreeTextRange);
                string        word  = wordRange.Word;

                if (decl.DeclaredName != word)
                {
                    if ((IdentifierResolver.IsIdentifier(decl, _solution, word, _identifierSettings.IdentifierLookupScope) ||
                         IdentifierResolver.IsKeyword(decl, _solution, word)) &&
                        IdentifierResolver.AnalyzeForMetaTagging(word, _xmlDocumentationSettings.CompiledWordsToIgnoreForMetatagging))
                    {
                        consumer.AddHighlighting(
                            new CanBeSurroundedWithMetatagsHighlight(word, range, decl, _solution),
                            range);
                    }
                    else if (spellCheck)
                    {
                        this.CheckWordSpelling(decl, wordRange, consumer, range);
                    }
                }
            }
        }
Пример #15
0
 public XmlDocLexer(IDocCommentBlock docCommentBlock)
 {
     _myDocCommentBlock = docCommentBlock;
     Start();
 }
 public XmlCommentReflowableBlockLexer(IDocCommentBlock docCommentBlock)
 {
     _docLexer = new XmlDocLexer(docCommentBlock);
     _docLexer.Start();
 }
Пример #17
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="blockNode"></param>
 /// <param name="maxLineLength"></param>
 /// <returns></returns>
 public string Reflow(IDocCommentBlock blockNode, int maxLineLength)
 {
     return(ReflowToLineLength(Parse(blockNode), maxLineLength));
 }
Пример #18
0
 public void Process(IDocCommentBlock docCommentBlockNode)
 {
 }
Пример #19
0
 public void SetDocCommentBlock(IDocCommentBlock block)
 {
     _classDeclaration.SetDocCommentBlock(block);
 }
Пример #20
0
 public void SetDocCommentBlock(IDocCommentBlock block)
 {
     _classDeclaration.SetDocCommentBlock(block);
 }