Skip to content

Macro expansion sometimes adds leading spaces inside string literals #1786

@tgoyne

Description

@tgoyne

Description

struct Names: MemberMacro {
    public static func expansion(
        of node: AttributeSyntax,
        providingMembersOf declaration: some DeclGroupSyntax,
        in context: some MacroExpansionContext
    ) throws -> [DeclSyntax] {
        guard let declaration = declaration.as(ClassDeclSyntax.self) else { return [] }
        let className = declaration.identifier.trimmed
        let names = declaration.memberBlock.members.compactMap { (member) -> String? in
            guard let property = member.decl.as(VariableDeclSyntax.self),
                  let binding = property.bindings.first,
                  let identifier = binding.pattern.as(IdentifierPatternSyntax.self)
            else {
                return nil
            }
            return identifier.identifier.text
        }
        let body = names.map { name in
            ExprSyntax("\(literal: name): \\\(className).\(raw: name)")
        }
        return ["""
        public static var names: [String: AnyKeyPath] = [\(raw: body.map(\.trimmedDescription).joined(separator: ", "))]
        public static var names2: [String: AnyKeyPath] = [\(raw: body.map(\.trimmedDescription).joined(separator: ", "))]
        """]
    }
}
assertMacroExpansion(
    #"""
    @Names class Foo {
        var value1: Int
        var value2: Int
        var value3: Int
    }
    """#,
    expandedSource: #"""
    @Names class Foo {
        var value1: Int
        var value2: Int
        var value3: Int
        public static var names: [String: AnyKeyPath] = ["value1": \Foo.value1, "value2": \Foo.value2, "value3": \Foo.value3]
        public static var names2: [String: AnyKeyPath] = ["value1": \Foo.value1, "value2": \Foo.value2, "value3": \Foo.value3]
    }
    """#,
    macros: [
        "Names": Names.self,
    ])

The actual result of this macro is:

@Names class Foo {
    var value1: Int
    var value2: Int
    var value3: Int
    public static var names: [String: AnyKeyPath] = ["value1": \Foo.value1, "value2": \Foo.value2, "value3": \Foo.value3]
    public static var names2: [String: AnyKeyPath] = [" value1": \Foo.value1, " value2": \Foo.value2, " value3": \Foo.value3]
}

Somehow each of the string literals in names2 has add a space added to the beginning even though it is generated by the exact same code as names, which does not have the spaces.

Steps to Reproduce

No response

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