Discrepancy between swift-ast-explorer and swift-syntax

While I understand the swift-ast-explorer is independent of swift-syntax, but the swift-syntax README links this tool for interactive exploration. Most of the use-cases have similar structure when parsed in swift-syntax and swift-ast-explorer, but I am encountering a specific use case during macro development.

If I look at @CodedAs(nil as String?) syntax tree with swift-syntax with following code:

let attribute = AttributeSyntax(stringLiteral: "@CodedAs(nil as String?)")
print(attribute.debugDescription)

it looks like following

AttributeSyntax
├─atSign: atSign
├─attributeName: IdentifierTypeSyntax
│ ╰─name: identifier("CodedAs")
├─leftParen: leftParen
├─arguments: LabeledExprListSyntax
│ ╰─[0]: LabeledExprSyntax
│   ╰─expression: SequenceExprSyntax
│     ╰─elements: ExprListSyntax
│       ├─[0]: NilLiteralExprSyntax
│       │ ╰─nilKeyword: keyword(SwiftSyntax.Keyword.nil)
│       ├─[1]: UnresolvedAsExprSyntax
│       │ ╰─asKeyword: keyword(SwiftSyntax.Keyword.as)
│       ╰─[2]: TypeExprSyntax
│         ╰─type: OptionalTypeSyntax
│           ├─wrappedType: IdentifierTypeSyntax
│           │ ╰─name: identifier("String")
│           ╰─questionMark: postfixQuestionMark
╰─rightParen: rightParen

Notice that nil as String? is parsed as SequenceExprSyntax by swift-syntax. But when trying with swift-ast-explorer, nil as String? is parsed as AsExprSyntax.

swift-ast-explorer seems to be parsing correctly here according to documentation of AsExprSyntax. How do I get this behaviour from swift-syntax? Is this a bug in swift-syntax?

The difference is that AST Explorer folds expressions by default while SwiftSyntax does not right in the parsing step. You can change that in AST Explorer:

1 Like

Thanks @SimplyDanny, is there any way I can fold sequence expression from swift-syntax?

You need to import SwiftOperators and then call OperatorTable.standardOperators.foldAll(syntax) on your syntax tree. This only works as long as you're using default operators only. If the syntax tree contains your own operators and precedence groups, you need to define your own OperatorTable as well.

1 Like

Thanks @SimplyDanny for helping, that OperatorTable.standardOperators.foldAll API handles my use-case.