예제 #1
0
        private void AddCommentToSideOfAstValue(ParseTreeNode owner, Token comment, CommentPlacement commentPlacement, int?lineIndexDistanceFromOwnerExplicit)
        {
            // first we calculate the lineIndexDistanceFromOwner, then we find a proper node with a non-null astNode to decorate (it can be in another line)
            int lineIndexDistanceFromOwner = lineIndexDistanceFromOwnerExplicit ?? Math.Abs(comment.Location.Line - owner.Span.Location.Line);

            owner = Util.Recurse(owner, GetParent).First(_parseTreeNode => _parseTreeNode.AstNode != null);
            object astValue = GrammarHelper.AstNodeToValue(owner.AstNode);

            Comments domainComments = astValue.GetComments();

            if (domainComments == null)
            {
                domainComments = new Comments();
                astValue.SetComments(domainComments);
            }

            var commentList = commentPlacement == CommentPlacement.OwnerLeft
                ? domainComments.left
                : domainComments.right;

            commentList.Add(CommentToDomainComment(comment, owner, commentPlacement, lineIndexDistanceFromOwner));

            decoratedComments.Add(comment);
        }
예제 #2
0
        private void StoreAstValueToParseTreeNodeRecursive(ParseTreeNode currentNode, int nodeIndex, object astValueParent)
        {
            object astValue = GrammarHelper.AstNodeToValue(currentNode.AstNode);

            if (astValue != null && astValue.GetType().IsClass&& !astValueToParseTreeNode.ContainsKey(astValue))
            {
                astValueToParseTreeNode.Add(astValue, currentNode);
            }

            if (astValue != null && astValue.GetDirectParent() == null)
            {
                astValue.SetDirectParent(astValueParent);
            }

            foreach (var parseTreeChild in currentNode.ChildNodes.Select((parseTreeChild, childIndex) => new { Value = parseTreeChild, Index = childIndex }))
            {
                parseTreeNodeToParent.Add(parseTreeChild.Value, currentNode);
                StoreAstValueToParseTreeNodeRecursive(parseTreeChild.Value, parseTreeChild.Index, astValueParent: astValue);
            }

            if (currentNode.Comments != null && currentNode.Comments.Count > 0)
            {
                bool isTextInLineAtLeftOfFirstComment = IsTextInLineAtLeftOfComment(currentNode.Comments[0]);
                int  lineIndexForFirstComment         = currentNode.Comments[0].Location.Line;

                foreach (Token comment in currentNode.Comments)
                {
                    if (decoratedComments.Contains(comment))
                    {
                        continue;   // we have already decorated this comment
                    }
                    ParseTreeNode parentNode = GetParent(currentNode);

                    bool isCommentInLineOfFirstComment = comment.Location.Line == lineIndexForFirstComment;
                    bool isTextInLineAtLeftOfComment   = isTextInLineAtLeftOfFirstComment && isCommentInLineOfFirstComment;

                    if (!isTextInLineAtLeftOfComment && parentNode != null && parentNode.Comments.Contains(comment) &&
                        parentNode.Span.Location.Line == currentNode.Span.Location.Line && !(GrammarHelper.AstNodeToValue(parentNode.AstNode) is IEnumerable))
                    {
                        /*
                         * Try to go up so we decorate the comment on the largest "subparsetree", but stop before lists
                         * */
                        continue;
                    }

                    if (isTextInLineAtLeftOfComment && currentLine != null && comment.Location.Line == currentLine.Span.Location.Line && currentLine.AstNode != null)
                    {
                        /*
                         * The comment belongs to the previous node (they are in the same line).
                         *
                         * Now we have one of the followings:
                         *
                         * code_prev (*comment*) code_this
                         * */

                        AddCommentToRightOfAstValue(currentLine, comment);
                    }
                    else if (isTextInLineAtLeftOfComment && prevLine != null && comment.Location.Line == prevLine.Span.Location.Line && prevLine.AstNode != null)
                    {
                        /*
                         * The comment belongs to the previous node (they are in the same line).
                         *
                         * code_prev (*comment*)
                         * code_this
                         * */

                        AddCommentToRightOfAstValue(prevLine, comment);
                    }
                    else if (currentNode.AstNode != null)
                    {
                        AddCommentToLeftOfAstValue(currentNode, comment);         // the comment belongs to this node
                    }
                    else if (nodeIndex > 0)
                    {
                        // could not decorate comment, because we have no ast (if nodeIndex == 0 then Irony has already copied it onto the parent)

                        Debug.Assert(parentNode != null);

                        if (currentLine != null)
                        {
                            AddCommentToRightOfAstValue(currentLine, comment);     // decorate the comment onto currentLine
                        }
                        else
                        {
                            parentNode.Comments.Add(comment);   // copy the comment onto the parent and handle it there
                        }
                    }
                }
            }

            if (currentLine == null || currentNode.Term is Terminal || currentNode.Span.Location.Line == currentLine.Span.Location.Line)
            {
                if (currentLine != null && currentNode.Span.Location.Line > currentLine.Span.Location.Line)
                {
                    prevLine = currentLine;
                }

                currentLine = currentNode;
            }
        }