Swift Syntax Comment Trivia - Expected prefixes

Hello! I am working on a project that does some automatic code generation using SwiftSyntax and SwiftSyntaxBuilder. As part of this project, I want to put in a comment at the top of the file warning users to not modify the file and make it obvious that the code was automatically generated. I was trying to use the .lineComment(String) static member of the Trivia (or TriviaPiece) types and I expected that the comment would automatically be prefixed with the expected // and space for use in code. (For example, Trivia.lineComment("No comment") would be written as // No Comment when sent through a BasicFormat Object or similar SyntaxRewriter). I was surprised to find that this is not the case and was wondering before I write an issue on GitHub whether this behavior is intentional or a bug. If it is intentional, I'm not entirely sure if I'm missing something regarding this to more easily generate these comments.

At the moment my comment generation consists of constructing the comment in the leadingTrivia of the syntax node that appears after the comment. For example:

VariableDeclSyntax(leadingTrivia: [.newlines(2), .lineComment("// These members are always generated irrespective of the contents of the generated files. They are intended to exclusively centralize code symbols that would otherwise be repeated frequently."), .newlines(1)], modifiers: [DeclModifierSyntax(name: .keyword(.private)), DeclModifierSyntax(name: .keyword(.static))], .let, name: PatternSyntax(IdentifierPatternSyntax(identifier: "decoder")), initializer: InitializerClauseSyntax(value: ExprSyntax(stringLiteral: "\(configuration.decoderExpression)"))) 

outputs

// These members are always generated irrespective of the contents of the generated files. They are intended to exclusively centralize code symbols that would otherwise be repeated frequently. private static let decoder = JSONDecoder() 

in this project (with example data having been added).

This post is a repost of something I posted on the Apple Developer Forums. I was recommended over there to repost on here.

That behavior is intentional. The using lineComment is essentially just the classification of the comment, and the associated value is the raw content of the trivia.

While stripping the // for line comments seems like a reasonable thing to do, things get a lot more ambiguous for block comments. For example, what would you expect .blockComment("abc\ndef") to produce? The following seem equally valid options and thus it’s better to be explicit about the user’s intention.

/* abc def */ 
/* abc def */ 

When attached to a node that is indented.

 /* abc def */ 

Also, Please add a `TriviaPiece.commentValue` property · Issue #1890 · swiftlang/swift-syntax · GitHub is related, but it goes from trivia to content while you are going the other way round.

And just for your information, if you import SwiftSyntaxBuilder you should be able to create trivia from a string literal, ie. use the following, in case you prefer that.

leadingTrivia: """ //// These members are always generated irrespective of the contents of the generated files. They are intended to exclusively centralize code symbols that would otherwise be repeated frequently. """
2 Likes