mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
114 lines
4.0 KiB
Swift
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: {{^}}}"
|