// REQUIRES: swift_swift_parser // RUN: %empty-directory(%t) // RUN: split-file --leading-lines %s %t // Check that a macro is automatically formatted and that it keeps any leading // comments (but not whitespace). // Create a plugin that adds a new function as a member without any trivia // RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroPlugin) -module-name=MacroPlugin %t/MacroPlugin.swift -g -no-toolchain-stdlib-rpath //--- MacroPlugin.swift import SwiftSyntax import SwiftSyntaxBuilder import SwiftSyntaxMacros public struct AddNamedFuncMacro: MemberMacro { public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { // TODO: Newline shouldn't be required here. BasicFormat should be adding // it. let newFunc = FunctionDeclSyntax( leadingTrivia: [.newlines(1), .docLineComment("/// My member macro function!"), .newlines(1)], modifiers: ModifierListSyntax([ DeclModifierSyntax(name: .keyword(.public)) ]), identifier: .identifier("newFunc"), signature: FunctionSignatureSyntax( input: ParameterClauseSyntax( parameterList: FunctionParameterListSyntax([])) ), body: CodeBlockSyntax( statements: CodeBlockItemListSyntax([ CodeBlockItemSyntax(item: .expr(ExprSyntax("_ = 1"))) ]) ) ) return [ DeclSyntax(newFunc), ] } } public struct AddPreformattedFuncMacro: MemberMacro { public static var formatMode: FormatMode = .disabled public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { let newFunc: DeclSyntax = """ /// My preformatted member macro function! public func preformattedFunc() { _ = 2 } """ return [ newFunc, ] } } //--- test.swift @attached( member, names: named(newFunc) ) public macro AddNamedFunc() = #externalMacro(module: "MacroPlugin", type: "AddNamedFuncMacro") @attached( member, names: named(preformattedFunc) ) public macro AddPreformattedFunc() = #externalMacro(module: "MacroPlugin", type: "AddPreformattedFuncMacro") // RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=%(line+1):2 %t/test.swift -- -target %target-triple -load-plugin-library %t/%target-library-name(MacroPlugin) %t/test.swift | %FileCheck -check-prefix=EXPAND -strict-whitespace %s @AddNamedFunc public struct ExpandTest { public func existingFunc() {} } // EXPAND: [[@LINE-1]]:1-[[@LINE-1]]:1 (@__swiftmacro_4test10ExpandTest12AddNamedFuncfMm_.swift) "/// My member macro function! // EXPAND-NEXT: {{^}}public func newFunc() { // EXPAND-NEXT: {{^}} _ = 1 // EXPAND-NEXT: {{^}}}" // RUN: %sourcekitd-test -req=refactoring.inline.macro -pos=%(line+1):1 %t/test.swift -- -target %target-triple -load-plugin-library %t/%target-library-name(MacroPlugin) %t/test.swift | %FileCheck -check-prefix=INLINE %s @AddNamedFunc public struct InlineTest { public func existingFunc() {} } // INLINE: [[@LINE-1]]:1-[[@LINE-1]]:1 (@__swiftmacro_4test10InlineTest12AddNamedFuncfMm_.swift) " // INLINE-EMPTY: // INLINE-NEXT: /// My member macro function! // INLINE-NEXT: {{^}}public func newFunc() { // INLINE-NEXT: {{^}} _ = 1 // INLINE-NEXT: {{^}}} // INLINE-NEXT: {{^}}" // RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=%(line+1):2 %t/test.swift -- -target %target-triple -load-plugin-library %t/%target-library-name(MacroPlugin) %t/test.swift | %FileCheck -check-prefix=PREFORMATTED -strict-whitespace %s @AddPreformattedFunc public struct PreformattedTest { public func existingFunc() {} } // PREFORMATTED: [[@LINE-1]]:1-[[@LINE-1]]:1 (@__swiftmacro_4test16PreformattedTest03AddB4FuncfMm_.swift) " // PREFORMATTED-NEXT: {{^}} /// My preformatted member macro function! // PREFORMATTED-NEXT: {{^}}public func preformattedFunc() { // PREFORMATTED-NEXT: {{^}}_ = 2 // PREFORMATTED-NEXT: {{^}}} // PREFORMATTED-NEXT: {{^}}"