swiftlang / swiftlang/swift-syntax

Required spacing is not added in `SwiftSyntaxBuilder` for interpolated syntax node

Open
#2,107 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
3.7k
Forks
553
Avg merge
5d 13h
Merged PRs (30d)
16

Description

### Description

For syntax nodes like `FunctionEffectSpecifiersSyntax` and `FunctionParameterSyntax`, some spacings are required internally. However, if a handcraft node is interpolated into another expression string, `SwiftSyntaxBuilder` fails to add these spacing, causing the parser to fail and the builder result being wrong.

### Steps to Reproduce

```swift
let functionPrameterClause = FunctionParameterClauseSyntax {
FunctionParameterSyntax(firstName: "_", secondName: "name", type: TypeSyntax("String"))
FunctionParameterSyntax(firstName: "description", type: TypeSyntax("String"))
}
let functionSignature = FunctionSignatureSyntax(
parameterClause: functionPrameterClause,
effectSpecifiers: .init(asyncSpecifier: .keyword(.async), throwsSpecifier: .keyword(.throws))
)
assertBuildResult(functionSignature, "(_ name: String, description: String) async throws") // OK
let initializerDecl = InitializerDeclSyntax(signature: functionSignature) {
"self.name = name"
"self.description = description"
}
assertBuildResult(
initializerDecl,
"""
init(_ name: String, description: String) async throws {
self.name = name
self.description = description
}
"""
) // OK
let initializerDeclFromString = try InitializerDeclSyntax("init\(functionSignature)") {
"self.name = name"
"self.description = description"
}
assertBuildResult(
initializerDeclFromString,
"""
init(_ name: String, description: String) async throws {
self.name = name
self.description = description
}
"""
) // Error
```
Outputs:
```
xctest [ParseError] Parsing a `DeclSyntax` node from string interpolation produced the following parsing errors.
Set a breakpoint in `SyntaxParseable.logStringInterpolationParsingError()` to debug the failure.
1 │ init(_name:String,description:String)asyncthrows {}
│ ╰─ error: unexpected code 'asyncthrows' in initializer
error: Test failed - Actual output (+) differed from expected output (-):
–init(_ name: String, description: String) async throws {
+init(_name: String, description: String) {
self.name = name
self.description = description
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.