Macros & SwiftSyntax: Creating a parameter list with line breaks

So far I'm successfully creating a parameter list where individual elements are created like this:

LabeledExprSyntax(label: "queries", expression: parameterTuples(queryParams))

(where parameterTuples() creates a particular array of tuples that I need)

What I want to do next is put each parameter on its own line in the output. But if I add leadingTrivia: [.newlines(1)] to the call, the colon gets lost, turning from queries: [(···)] into queries[(···)]. If I add an explicit colon parameter with ":" as TokenSyntax, then the space appears before the colon instead of after, which is not technically wrong but it is undesirable. If I add the newline in the trailing trivia, it appears before the trailing comma.

So how can I add that newline without messing up the rest of the parameter?

I ended up getting it to work by calling it like this:

LabeledExprSyntax(leadingTrivia: [.newlines(1)],
                  label: "queries: ",
                  expression: parameterTuples(queryParams))

putting the colon and space explicitly in the label, which seems really weird. I thought the parser would complain, but it doesn't, and I get the output formatted the way I want.

Is it a bug that adding a leading newline messes up the label like that?

Not an answer, but just in case, are you aware that many frequently used swift-syntax types take literal string as their input? I have written some macros but haven't found I need to generate code this way.

1 Like

I don't think using

LabeledExprSyntax(leadingTrivia: [.newlines(1)],
                  label: "queries: ",
                  expression: parameterTuples(queryParams))

is a good idea. While that might work now, it can break at any later point.

I would say, it's a bug that the colons get removed when you add leading trivia.

The following works properly:

LabeledExprSyntax(label: "queries", expression: params)
    .with(\.leadingTrivia, .newlines(1))

It first creates the node and after that attaches the newline retaining the colon.

Thanks. I thought I had tried that, but I guess it was just something similar. This does work for me.