Skip to content

Required spacing is not added in SwiftSyntaxBuilder for interpolated syntax node #2107

Open
@stevapple

Description

@stevapple

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

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
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions