Files
swift-mirror/test/SourceKit/Macros/macro_formatting.swift
Ben Barham fe2104ca99 [Macros] Automatically format expanded macros
Rather than requiring macro implementations to add required whitespace
and indentation, basic format all macro expansions. Right now this uses
the default four space indentation, we can consider having that inferred
later. Macros can opt-out of automatic formatting by implementing
`formatMode` and setting it to `.disabled`.

Also moves the extra newlines before/after expansions to a new "Inline
Macro" refactoring.

Resolves rdar://107731047.
2023-04-27 21:24:46 -07:00

114 lines
4.0 KiB
Swift

// 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) "/// My preformatted member macro function!
// PREFORMATTED-NEXT: {{^}}public func preformattedFunc() {
// PREFORMATTED-NEXT: {{^}}_ = 2
// PREFORMATTED-NEXT: {{^}}}"