Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 16, 2025

Fix: DocumentationCommentTriviaSyntax.Ancestors() returns empty collection

Problem

  • Ancestors(ascendOutOfTrivia: true) on DocumentationCommentTriviaSyntax returned no ancestors
  • AncestorsAndSelf(ascendOutOfTrivia: true) correctly returned all ancestors including self

Root Cause

The Ancestors method in SyntaxNode.cs was using this.Parent directly, which is null for structured trivia nodes. It should use the GetParent helper method (like AncestorsAndSelf does) which knows how to ascend out of structured trivia when ascendOutOfTrivia is true.

Solution

Changed Ancestors to use GetParent(this, ascendOutOfTrivia) instead of just this.Parent.

Changes Made

  • Analyze the issue and identify root cause
  • Fix the Ancestors method in SyntaxNode.cs
  • Add test case for DocumentationCommentTriviaSyntax.Ancestors()
  • Add test case for DefineDirectiveTriviaSyntax (another structured trivia type)
  • Build and run tests to verify fix (all 197 SyntaxNodeTests pass)
  • Run code review and address comments
  • Add clarifying comment about directive trivia test behavior
  • Add WorkItem attributes and use raw string literals

Testing

  • All existing 197 tests in SyntaxNodeTests pass
  • Added 2 new tests specifically for structured trivia:
    • TestAncestorsOfDocumentationCommentTrivia - tests doc comment trivia
    • TestAncestorsOfDirectiveTrivia - tests preprocessor directive trivia

Fixes #46964

Original prompt

This section details on the original issue you should resolve

<issue_title>'DocumentationCommentTriviaSyntax.Ancestors(true)' does not return any ancestors but 'AncestorsAndSelf(true)' does</issue_title>
<issue_description>Version Used:
3.6

Steps to Reproduce:

  1. Get the DocumentationCommentTriviaSyntax that represents the comment in following snippet:
public class TestMe
{
    /// <summary>
    /// Some summary.
    /// </summary>
    /// <value>
    /// Some value.
    /// </value>
    private int i;
}
  1. Invoke SyntaxNode.Ancestors() and SyntaxNode.AncestorsAndSelf(true) on the DocumentationCommentTriviaSyntax.
  2. Compare the results and find out that Ancestors() does neither return the FieldDeclarationSyntax, nor the ClassDeclarationSyntax, nor the CompilationUnitSyntax.
    In contrast, AncestorsAndSelf() returns them all.

Expected Behavior:
Invoking SyntaxNode.Ancestors(true) on a DocumentationCommentTriviaSyntax returns all ancestors, similar to SyntaxNode.AncestorsAndSelf(true), except the trivia (no self).

Actual Behavior:
SyntaxNode.Ancestors(true) invoked on a DocumentationCommentTriviaSyntax returns no ancestors.

SyntaxNode.AncestorsAndSelf(true) invoked on the same DocumentationCommentTriviaSyntax not only returns the trivia as expected, but also all the other ancestors that SyntaxNode.Ancestors(true) is missing to return.</issue_description>

<agent_instructions>See conversation for likely fix.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@CyrusNajmabadi ```c# public IEnumerable Ancestors(bool ascendOutOfTrivia = true) { return this.Parent? .AncestorsAndSelf(ascendOutOfTrivia) ?? SpecializedCollections.EmptyEnumerable(); } ```

should likely be updated to be:

        public IEnumerable<SyntaxNode> Ancestors(bool ascendOutOfTrivia = true)
        {
            return GetParent(this, ascendOutOfTrivia)?
                .AncestorsAndSelf(ascendOutOfTrivia) ??
                SpecializedCollections.EmptyEnumerable<SyntaxNode>();
        }
```</body></comment_new>
</comments>

Fixes #46964


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits October 16, 2025 22:34
- Changed Ancestors() to use GetParent() instead of just Parent property
- This allows it to properly ascend out of structured trivia (like DocumentationCommentTriviaSyntax)
- Added tests for DocumentationCommentTriviaSyntax and DefineDirectiveTriviaSyntax

Co-authored-by: CyrusNajmabadi <[email protected]>
Copilot AI changed the title [WIP] Fix ancestors method to return expected ancestors Fix SyntaxNode.Ancestors() to work correctly with structured trivia Oct 16, 2025
Copilot finished work on behalf of CyrusNajmabadi October 16, 2025 22:40
Copilot AI requested a review from CyrusNajmabadi October 16, 2025 22:40
Assert.Equal(SyntaxKind.AddExpression, nodes[7].Kind());
}

[Fact]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot add a WorkItem attribute. And use a raw string literal for the test. This applies to all tests you added.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in commit e8d5c67. Added [WorkItem("https://github.com/dotnet/roslyn/issues/46964")] attribute to both tests and converted the verbatim strings to raw string literals.

- Added [WorkItem] attribute referencing issue #46964 to both test methods
- Converted verbatim strings to raw string literals (""") for better formatting

Co-authored-by: CyrusNajmabadi <[email protected]>
Copilot AI requested a review from CyrusNajmabadi October 16, 2025 22:48
Copilot finished work on behalf of CyrusNajmabadi October 16, 2025 22:48
@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review October 17, 2025 17:11
@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner October 17, 2025 17:11
@CyrusNajmabadi
Copy link
Member

@dotnet/roslyn-compiler ptal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

'DocumentationCommentTriviaSyntax.Ancestors(true)' does not return any ancestors but 'AncestorsAndSelf(true)' does

2 participants