Skip to content

Add JSDoc generation from C# XML documentation comments#78

Merged
ArcadeMode merged 21 commits intomasterfrom
copilot/add-comment-info-property
Feb 18, 2026
Merged

Add JSDoc generation from C# XML documentation comments#78
ArcadeMode merged 21 commits intomasterfrom
copilot/add-comment-info-property

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 16, 2026

JSDoc Generation from C# XML Comments

Implementation Complete ✅

All tasks completed successfully:

  • Explore codebase and understand structure
  • Create CommentInfo class and CommentInfoBuilder
  • Update Info classes to include CommentInfo property
  • Update InfoBuilder classes to build CommentInfo
  • Create JSDoc renderer
  • Integrate JSDoc rendering into TypeScript renderers
  • Create comprehensive test file (39 tests, all passing)
    • Tests for class, method, and property comments
    • Tests for params, returns, and exceptions
    • Tests for bold (<b>) and italic (<i>) tags
    • Tests for inner tag parsing in params, returns, and throws
    • Tests for code tags and paramref
    • Tests for <example> tag (treated like <c> and <code>)
    • Test for unknown tags (gracefully handled - renders inner text)
    • Tests for <br> tag for line breaks
    • Tests for <br> inside <b>, <c>, and list tags
    • Tests for <list> tags with various structures (spread over multiple lines)
    • Test demonstrating lists start on new line without <br> tag before them
    • Tests for multiple <paramref> tags
    • Tests for exceptions without namespaces (Roslyn adds them automatically)
    • Test for unknown exception type (missing import) - !: prefix automatically removed
    • Test for empty param name attribute (ignored in output)
    • Test for empty exception cref attribute (ignored in output)
    • Test for nested class in see tag - now preserves full path including namespace (e.g., N1.OuterClass.InnerClass)
    • Tests for malformed XML (missing closing tags) - confirms no JSDoc is rendered
  • Run existing tests to ensure no regressions (526 passed, 1 skipped)
  • Address all code review feedback
    • Removed namespace stripping logic - see tags now keep full type path
    • Simpler and more correct: handles 3+ layer nested classes and multi-segment namespaces
    • Updated test expectations to reflect full type paths
  • Security scan (0 vulnerabilities found)
  • Manual validation with sample code

Features Implemented

  1. XML Comment Parsing:

    • Strips all line breaks from XML source before parsing for simplified implementation
    • Parses <summary>, <remarks>, <param>, <returns>, <exception> tags
    • Transforms inner tags: <c> → backticks, <paramref> → backticks, <see> → backticks
    • <see> tags now preserve full type path including namespace for clarity and correctness
    • Supports <example> → backticks (treated like code tags)
    • Supports <b>**bold** and <i>*italic*
    • Supports <br> → single line break using Environment.NewLine
    • Supports <list> tags with <item>, <term>, <description>, and <listheader> elements
    • Lists start on new line with single line break (no blank lines)
    • Lists have items on separate lines with single line breaks
    • Handles list items with just text content (outputs text directly)
    • Handles listheader with various formats (term/description, only term, or straight text)
    • Handles malformed XML gracefully (returns null when XML parsing fails)
    • Handles unknown exception types - automatically removes !: prefix from Roslyn error references
    • Ignores empty name attributes in <param> tags
    • Ignores empty cref attributes in <exception> tags
    • Unknown tags gracefully handled - renders inner text without wrapper
    • Normalizes whitespace (multiple spaces/tabs become single space)
    • Uses modern C# range operators
  2. JSDoc Generation:

    • Renders JSDoc comments for classes, methods, and properties
    • Uses chained ctx.Append().AppendLine() calls to avoid string allocations
    • Uses Environment.NewLine consistently throughout for cross-platform compatibility
    • Single line breaks only - no blank lines for cleaner output
    • Generates @param, @returns, and @throws tags
    • Only renders JSDoc when comments exist (graceful null handling)
    • Roslyn automatically adds namespaces to exception types even when not specified
    • Unknown exception types have !: prefix automatically removed for cleaner output
  3. Test Coverage:

    • 39 comprehensive tests covering all comment scenarios
    • All 526 tests passing (1 skipped)

Code Quality

  • Zero security vulnerabilities (CodeQL scan)
  • Modern C# idioms (range operators, nullable reference types)
  • Highly refactored for maintainability:
    • IsEmpty() method now on CommentInfo class (proper encapsulation)
    • Extracted helper methods (ExtractTypeFromCref, RenderListItem)
    • Inverted conditionals for clearer early returns
    • Deduplicated switch cases
    • Removed unnecessary temp variables
    • Renamed ProcessInnerTags to ProcessFormatTags for better semantic clarity
    • Inlined CommentInfoBuilder expressions at all usage sites
    • Simplified GetReferenceText - removed flawed namespace stripping logic
    • No "what" comments, only "why" comments where needed
    • Validation for empty attributes
  • Simplified implementation: Line breaks stripped from XML source upfront
  • Consistent use of Environment.NewLine for cross-platform compatibility
  • Optimized rendering using chained Append calls (no intermediate string allocations)
  • Graceful handling of malformed XML and unknown types/tags
  • Example tag support for code samples
  • Roslyn-like behavior: XML source line breaks ignored, only explicit <br>, <list>, and list items create line breaks
  • Follows existing TypeShim patterns and conventions
Original prompt

for classinfo, methodinfo and propertyinfo I want to add a new property. the property should be set in the respective infobuilder. the new property will be of type CommentInfo? which gets a builder too. the builder will take the respective symbol as a constructor parameter and call the method to get the xml comment. if there is no comment the builder returns null. if there is a comment string it should be xml parsed to get a set of properties that will be used downstream to render the same content but in jsdoc format.

  • Description: content of the summary tag and remark tag appended. the summary tag can contain various inner tags. check the docs and transform these such that the output is jsdoc compatible i.e. tag or code tags are common.
  • Parameters: list of records ParameterCommentInfo that has the name and description. should also parse inner tags
  • returns: the return tag content. also parse inner tags
  • throws: type and description in record. also inner tags.

then we need a new typescript jsdoc renderer that can be used during property, method and class rendering to turn this object into valid jsdoc. this should only be used for the user class proxy and is not necessary for other typescript code generation

make sure existing tests are unaffected. we should only need to add the calls to the jsdoc renderer into the existing renderers for typescript. add a new test file that shows tests for properties methods and classes with comments and also permutations with and without parameter content, exception and returns information in the c# xml comment.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 6 commits February 16, 2026 23:26
Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
… endings

Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Copilot AI changed the title [WIP] Add CommentInfo property to classinfo, methodinfo, and propertyinfo Add JSDoc generation from C# XML documentation comments Feb 16, 2026
Copilot AI requested a review from ArcadeMode February 16, 2026 23:40
Copy link
Copy Markdown
Owner

@ArcadeMode ArcadeMode left a comment

Choose a reason for hiding this comment

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

Add a new class with tests to the generator.tests project that demonstrate various comments with different contents

…class

Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 17, 2026

Add a new class with tests to the generator.tests project that demonstrate various comments with different contents

Added a comprehensive test in commit a46561b that demonstrates a Calculator class with various comment types including:

  • Class documentation with summary and remarks
  • Methods with params, returns, and multiple exceptions
  • Properties with documentation (getter/setter and read-only)
  • Inner XML tag transformations (code tags and paramrefs)

The test validates all JSDoc features working together in a single realistic example. All 12 JSDoc tests pass.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 17, 2026

Test Results

  3 files  ± 0   17 suites  ±0   27s ⏱️ +3s
697 tests +41  693 ✅ +41  4 💤 ±0  0 ❌ ±0 
871 runs  +41  864 ✅ +41  7 💤 ±0  0 ❌ ±0 

Results for commit f000762. ± Comparison against base commit 3705083.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown
Owner

@ArcadeMode ArcadeMode left a comment

Choose a reason for hiding this comment

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

Remove the last added test (the comprehensive one) the rest is fine. Then change the new renderer to not use interpolation expressions, instead chain append and appendline calls on the render context to not cause unnecessary intermediate string allocations

Do add tests for rendering with other tags like bold and italics. Also show the inner tag parsing inside throws returns and params

… tests

Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 17, 2026

Remove the last added test (the comprehensive one) the rest is fine. Then change the new renderer to not use interpolation expressions, instead chain append and appendline calls on the render context ...

Changes completed in commit 00f462c:

  1. Removed the comprehensive test
  2. Refactored TypeScriptJSDocRenderer to use chained ctx.Append().AppendLine() calls instead of string interpolation
  3. Added 5 new tests demonstrating:
    • Bold tag (<b>) → **bold**
    • Italic tag (<i>) → *italic*
    • Inner tags in params (bold, code, italic)
    • Inner tags in returns (bold, code, italic)
    • Inner tags in throws (paramref, code, italic)

All 503 tests pass.

Copy link
Copy Markdown
Owner

@ArcadeMode ArcadeMode left a comment

Choose a reason for hiding this comment

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

.

Copy link
Copy Markdown
Owner

@ArcadeMode ArcadeMode left a comment

Choose a reason for hiding this comment

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

Add tests for comments with list and paramref. Also for exceptions without namespaces.

Finally also check how it processes missing closing tags for param bold and summary

…d XML

Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Copy link
Copy Markdown
Owner

@ArcadeMode ArcadeMode left a comment

Choose a reason for hiding this comment

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

Improve the code quality by adressing my review comments

Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 17, 2026

Improve the code quality by adressing my review comments

Addressed all code review comments in commit c144f81:

Code quality improvements:

  1. Extracted IsEmpty() method to check if CommentInfo has content
  2. Extracted ExtractTypeFromCref() helper method using string splitting by : (takes last segment)
  3. Inverted conditionals in BuildParameters and BuildThrows for early returns
  4. Inverted conditional in BuildDescription for early return
  5. Deduplicated list rendering with RenderListItem() local method
  6. Combined duplicate switch cases using or pattern
  7. Removed "what" comments, kept implementation clean

New tests:

  • TypeScriptUserClassProxy_ParamWithEmptyName_IgnoresParam - validates empty param name is ignored
  • TypeScriptUserClassProxy_ExceptionWithEmptyCref_IgnoresException - validates empty cref is ignored

All 525 tests pass (1 skipped).

Copy link
Copy Markdown
Owner

@ArcadeMode ArcadeMode left a comment

Choose a reason for hiding this comment

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

Fix review points

…pressions, rename method

Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 17, 2026

Fix review points

All review points addressed in commit 0273061:

  1. Moved IsEmpty() method to CommentInfo class
  2. Inlined method calls in Build() - removed temp variables
  3. Used ExtractTypeFromCref() in GetReferenceText method
  4. Renamed ProcessInnerTags to ProcessFormatTags
  5. Inlined CommentInfoBuilder expressions at all usage sites (MethodInfoBuilder, ClassInfoBuilder, PropertyInfoBuilder)

All 525 tests pass (1 skipped).

Copy link
Copy Markdown
Owner

@ArcadeMode ArcadeMode left a comment

Choose a reason for hiding this comment

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

Check case

Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com>
@ArcadeMode ArcadeMode marked this pull request as ready for review February 18, 2026 20:24
@ArcadeMode
Copy link
Copy Markdown
Owner

~300 lines of actual code, 2k are tests

@ArcadeMode ArcadeMode merged commit 046709a into master Feb 18, 2026
2 checks passed
@ArcadeMode ArcadeMode deleted the copilot/add-comment-info-property branch February 18, 2026 20:30
@ArcadeMode ArcadeMode mentioned this pull request Feb 18, 2026
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants