mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
305 lines
14 KiB
Swift
305 lines
14 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-build-swift -swift-version 5 -I %swift-host-lib-dir -L %swift-host-lib-dir -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath -swift-version 5
|
|
// RUNx: %target-swift-frontend -dump-ast -enable-experimental-feature FreestandingMacros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir %s -module-name MacroUser 2>&1 | %FileCheck --check-prefix CHECK-AST %s
|
|
|
|
// Diagnostics testing
|
|
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-experimental-feature FreestandingMacros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir -module-name MacroUser -DTEST_DIAGNOSTICS
|
|
|
|
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-experimental-feature FreestandingMacros -plugin-path %t -I %swift-host-lib-dir -module-name MacroUser -DTEST_DIAGNOSTICS
|
|
|
|
// RUN: not %target-swift-frontend -swift-version 5 -typecheck -enable-experimental-feature FreestandingMacros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir -module-name MacroUser -DTEST_DIAGNOSTICS -serialize-diagnostics-path %t/macro_expand.dia %s -emit-macro-expansion-files no-diagnostics > %t/macro-printing.txt
|
|
// RUN: c-index-test -read-diagnostics %t/macro_expand.dia 2>&1 | %FileCheck -check-prefix CHECK-DIAGS %s
|
|
|
|
// RUN: %FileCheck %s --check-prefix CHECK-MACRO-PRINTED < %t/macro-printing.txt
|
|
|
|
// Debug info SIL testing
|
|
// RUN: %target-swift-frontend -swift-version 5 -emit-sil -enable-experimental-feature FreestandingMacros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir %s -module-name MacroUser -o - -g | %FileCheck --check-prefix CHECK-SIL %s
|
|
|
|
// Debug info IR testing
|
|
// RUN: %target-swift-frontend -swift-version 5 -emit-ir -enable-experimental-feature FreestandingMacros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir %s -module-name MacroUser -o - -g | %FileCheck --check-prefix CHECK-IR %s
|
|
|
|
// Execution testing
|
|
// RUN: %target-build-swift -swift-version 5 -g -enable-experimental-feature FreestandingMacros -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir -L %swift-host-lib-dir %s -o %t/main -module-name MacroUser
|
|
// RUN: %target-run %t/main | %FileCheck %s
|
|
// REQUIRES: executable_test
|
|
|
|
// FIXME: Swift parser is not enabled on Linux CI yet.
|
|
// REQUIRES: OS=macosx
|
|
|
|
#if TEST_DIAGNOSTICS
|
|
@attached(peer)
|
|
macro Invalid() = #externalMacro(module: "MacroDefinition", type: "InvalidMacro")
|
|
|
|
@Invalid
|
|
struct Bad {}
|
|
// expected-note@-1 18 {{in expansion of macro 'Invalid' here}}
|
|
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce import
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce precedence group
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce macro
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce extension
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce '@main' type
|
|
// CHECK-DIAGS: error: declaration name 'MyMain' is not covered by macro 'Invalid'
|
|
// CHECK-DIAGS: error: declaration name 'Array' is not covered by macro 'Invalid'
|
|
// CHECK-DIAGS: error: declaration name 'Dictionary' is not covered by macro 'Invalid'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type 'BooleanLiteralType'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type 'ExtendedGraphemeClusterType'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type 'FloatLiteralType'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type 'IntegerLiteralType'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type 'StringLiteralType'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type 'UnicodeScalarType'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type '_ColorLiteralType'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type '_ImageLiteralType'
|
|
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type '_FileReferenceLiteralType'
|
|
|
|
// CHECK-DIAGS: CONTENTS OF FILE @__swiftmacro_9MacroUser3BadV7InvalidfMp_.swift
|
|
// CHECK-DIAGS: import Swift
|
|
// CHECK-DIAGS: precedencegroup MyPrecedence {}
|
|
// CHECK-DIAGS: @attached(member) macro myMacro()
|
|
// CHECK-DIAGS: extension Int {}
|
|
// CHECK-DIAGS: @main
|
|
// CHECK-DIAGS: struct MyMain {
|
|
// CHECK-DIAGS: static func main() {}
|
|
// CHECK-DIAGS: }
|
|
// CHECK-DIAGS: typealias Array = Void
|
|
// CHECK-DIAGS: typealias Dictionary = Void
|
|
// CHECK-DIAGS: typealias BooleanLiteralType = Void
|
|
// CHECK-DIAGS: typealias ExtendedGraphemeClusterType = Void
|
|
// CHECK-DIAGS: typealias FloatLiteralType = Void
|
|
// CHECK-DIAGS: typealias IntegerLiteralType = Void
|
|
// CHECK-DIAGS: typealias StringLiteralType = Void
|
|
// CHECK-DIAGS: typealias UnicodeScalarType = Void
|
|
// CHECK-DIAGS: typealias _ColorLiteralType = Void
|
|
// CHECK-DIAGS: typealias _ImageLiteralType = Void
|
|
// CHECK-DIAGS: typealias _FileReferenceLiteralType = Void
|
|
// CHECK-DIAGS: END CONTENTS OF FILE
|
|
#endif
|
|
|
|
@freestanding(expression) macro customFileID() -> String = #externalMacro(module: "MacroDefinition", type: "FileIDMacro")
|
|
@freestanding(expression) macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
|
|
@freestanding(expression) macro fileID<T: ExpressibleByStringLiteral>() -> T = #externalMacro(module: "MacroDefinition", type: "FileIDMacro")
|
|
@freestanding(expression) macro recurse(_: Bool) = #externalMacro(module: "MacroDefinition", type: "RecursiveMacro")
|
|
|
|
func testFileID(a: Int, b: Int) {
|
|
// CHECK: MacroUser/macro_expand.swift
|
|
print("Result is \(#customFileID)")
|
|
// CHECK-SIL: sil_scope [[MACRO_SCOPE:[0-9]+]] { loc "{{.*}}":1:1 parent @$s9MacroUser10testFileID1a1bySi_SitF06customdE0fMf_ {{.*}} }
|
|
// CHECK-SIL: sil_scope [[SRC_SCOPE:[0-9]+]] { loc "{{.*}}macro_expand.swift":[[@LINE-2]]
|
|
// CHECK-SIL: sil_scope {{[0-9]+}} { loc "{{.*}}":1:1 parent [[MACRO_SCOPE]] inlined_at [[SRC_SCOPE]] }
|
|
// CHECK-IR: !DISubprogram(name: "customFileID", linkageName: "$s9MacroUser10testFileID1a1bySi_SitF06customdE0fMf_"
|
|
|
|
|
|
// CHECK: Builtin result is MacroUser/macro_expand.swift
|
|
// CHECK-AST: macro_expansion_expr type='String'{{.*}}name=line
|
|
print("Builtin result is \(#fileID)")
|
|
}
|
|
|
|
testFileID(a: 1, b: 2)
|
|
|
|
@freestanding(expression) macro stringifyAndTry<T>(_ value: T) -> (T, String) =
|
|
#externalMacro(module: "MacroDefinition", type: "StringifyAndTryMacro")
|
|
|
|
func testStringify(a: Int, b: Int) {
|
|
let s = #stringify(a + b)
|
|
print(s)
|
|
|
|
// CHECK-AST: macro_expansion_expr type='(Int, String)'{{.*}}name=stringify
|
|
// CHECK-AST-NEXT: argument_list
|
|
// CHECK-AST: tuple_expr type='(Int, String)' location=Macro expansion of #stringify
|
|
|
|
let (b, s2) = #stringify({ () -> Bool in return true })
|
|
// CHECK-AST: macro_expansion_expr type='(() -> Bool, String)'{{.*}}name=stringify
|
|
// CHECK-AST-NEXT: argument_list
|
|
// CHECK-AST: tuple_expr type='(() -> Bool, String)' location=Macro expansion of #stringify
|
|
|
|
let (b2, s3) = #stringify<Double>(1 + 2)
|
|
// CHECK-AST: macro_expansion_expr type='(Double, String)'{{.*}}name=stringify
|
|
// CHECK-AST-NEXT: argument_list
|
|
// CHECK-AST: tuple_expr type='(Double, String)' location=Macro expansion of #stringify
|
|
|
|
_ = (b, b2, s2, s3)
|
|
}
|
|
|
|
public struct Outer {
|
|
var value: Int = 0
|
|
public func test() {
|
|
let (a, b) = #stringify(1 + value)
|
|
|
|
let (c, d) = #stringify({ x in
|
|
x + 1
|
|
})
|
|
|
|
_ = a
|
|
_ = b
|
|
_ = c
|
|
_ = d
|
|
}
|
|
}
|
|
|
|
// CHECK: (2, "a + b")
|
|
testStringify(a: 1, b: 1)
|
|
|
|
func maybeThrowing() throws -> Int { 5 }
|
|
|
|
#if TEST_DIAGNOSTICS
|
|
@freestanding(expression) @discardableResult
|
|
macro discardableStringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
|
|
|
|
func testDiscardableStringify(x: Int) {
|
|
#stringify(x + 1) // expected-warning{{expression of type '(Int, String)' is unused}}
|
|
#discardableStringify(x + 1)
|
|
}
|
|
#endif
|
|
|
|
func testStringifyWithThrows() throws {
|
|
// Okay, we can put the try inside or outside
|
|
_ = try #stringify(maybeThrowing())
|
|
_ = #stringify(try maybeThrowing())
|
|
|
|
#if TEST_DIAGNOSTICS
|
|
// FIXME: Lots of duplicate notes here
|
|
_ = #stringify(maybeThrowing()) // expected-note 4{{in expansion of macro 'stringify' here}}
|
|
|
|
// CHECK-DIAGS: @__swiftmacro_9MacroUser23testStringifyWithThrowsyyKF9stringifyfMf1_.swift:1:2: error: call can throw but is not marked with 'try'
|
|
#endif
|
|
|
|
// The macro adds the 'try' for us.
|
|
_ = #stringifyAndTry(maybeThrowing())
|
|
}
|
|
|
|
|
|
@freestanding(expression) macro addBlocker<T>(_ value: T) -> T = #externalMacro(module: "MacroDefinition", type: "AddBlocker")
|
|
|
|
struct OnlyAdds {
|
|
static func +(lhs: OnlyAdds, rhs: OnlyAdds) -> OnlyAdds { lhs }
|
|
}
|
|
|
|
func testAddBlocker(a: Int, b: Int, c: Int, oa: OnlyAdds) {
|
|
_ = #addBlocker(a * b * c)
|
|
#if TEST_DIAGNOSTICS
|
|
_ = #addBlocker(a + b * c) // expected-error{{blocked an add; did you mean to subtract? (from macro 'addBlocker')}}
|
|
// expected-note@-1{{use '-'}}{{21-23=- }}
|
|
_ = #addBlocker(oa + oa) // expected-error{{blocked an add; did you mean to subtract? (from macro 'addBlocker')}}
|
|
// expected-note@-1{{in expansion of macro 'addBlocker' here}}
|
|
// expected-note@-2{{use '-'}}{{22-24=- }}
|
|
|
|
// CHECK-DIAGS: @__swiftmacro_9MacroUser14testAddBlocker1a1b1c2oaySi_S2iAA8OnlyAddsVtF03addE0fMf1_.swift:1:4: error: binary operator '-' cannot be applied to two 'OnlyAdds' operands [] []
|
|
// CHECK-DIAGS: CONTENTS OF FILE @__swiftmacro_9MacroUser14testAddBlocker1a1b1c2oaySi_S2iAA8OnlyAddsVtF03addE0fMf1_.swift:
|
|
// CHECK-DIAGS-NEXT: Original source range: {{.*}}macro_expand.swift:[[@LINE-6]]:7 - {{.*}}macro_expand.swift:[[@LINE-6]]:27
|
|
// CHECK-DIAGS-NEXT: oa - oa
|
|
// CHECK-DIAGS-NEXT: END CONTENTS OF FILE
|
|
|
|
_ = #addBlocker({ // expected-note{{in expansion of macro 'addBlocker' here}}
|
|
|
|
print("hello")
|
|
print(oa + oa) // expected-error{{blocked an add; did you mean to subtract? (from macro 'addBlocker')}}
|
|
// expected-note@-1{{use '-'}}
|
|
print(oa + oa) // expected-error{{blocked an add; did you mean to subtract? (from macro 'addBlocker')}}
|
|
// expected-note@-1{{use '-'}}
|
|
}())
|
|
|
|
// Check recursion.
|
|
#recurse(false) // okay
|
|
#recurse(true) // expected-note{{in expansion of macro 'recurse' here}}
|
|
#endif
|
|
}
|
|
|
|
@freestanding(expression) macro leftHandOperandFinder<T>(_ value: T) -> T = #externalMacro(module: "MacroDefinition", type: "LeftHandOperandFinderMacro")
|
|
|
|
|
|
// Test source location information.
|
|
func testSourceLocations(x: Int, yolo: Int, zulu: Int) {
|
|
// CHECK-MACRO-PRINTED: Source range for LHS is MacroUser/macro_expand.swift: [[@LINE+3]]:5-[[@LINE+3]]:13
|
|
// CHECK-MACRO-PRINTED: Source range for LHS is MacroUser/macro_expand.swift: [[@LINE+2]]:5-[[@LINE+2]]:6
|
|
_ = #leftHandOperandFinder(
|
|
x + yolo + zulu
|
|
)
|
|
}
|
|
|
|
// Make sure we don't crash with declarations produced by expansions.
|
|
@freestanding(expression) macro nestedDeclInExpr() -> () -> Void = #externalMacro(module: "MacroDefinition", type: "NestedDeclInExprMacro")
|
|
|
|
func testNestedDeclInExpr() {
|
|
let _: () -> Void = #nestedDeclInExpr
|
|
}
|
|
|
|
@freestanding(declaration, names: arbitrary) macro bitwidthNumberedStructs(_ baseName: String) = #externalMacro(module: "MacroDefinition", type: "DefineBitwidthNumberedStructsMacro")
|
|
// Test overload
|
|
@freestanding(declaration, names: arbitrary) macro bitwidthNumberedStructs(_ baseName: String, blah: Bool) = #externalMacro(module: "MacroDefinition", type: "DefineBitwidthNumberedStructsMacro")
|
|
// Test non-arbitrary names
|
|
@freestanding(declaration, names: named(A), named(B), named(foo), named(addOne))
|
|
macro defineDeclsWithKnownNames() = #externalMacro(module: "MacroDefinition", type: "DefineDeclsWithKnownNamesMacro")
|
|
|
|
// Macros adding to an enum
|
|
@attached(member, names: named(unknown), arbitrary)
|
|
public macro ExtendableEnum() = #externalMacro(module: "MacroDefinition", type: "ExtendableEnum")
|
|
|
|
@ExtendableEnum
|
|
enum ElementType {
|
|
case paper
|
|
}
|
|
|
|
print(ElementType.paper.unknown())
|
|
|
|
// FIXME: Declaration macro expansions in BraceStmt don't work yet.
|
|
//#bitwidthNumberedStructs("MyIntGlobal")
|
|
|
|
func testFreestandingMacroExpansion() {
|
|
// Explicit structs to force macros to be parsed as decl.
|
|
struct Foo {
|
|
#bitwidthNumberedStructs("MyIntOne")
|
|
}
|
|
|
|
// CHECK: MyIntOne8
|
|
print(Foo.MyIntOne8.self)
|
|
// CHECK: MyIntOne16
|
|
print(Foo.MyIntOne16.self)
|
|
// CHECK: MyIntOne32
|
|
print(Foo.MyIntOne32.self)
|
|
// CHECK: MyIntOne64
|
|
print(Foo.MyIntOne64.self)
|
|
|
|
struct Foo2 {
|
|
#bitwidthNumberedStructs("MyIntTwo", blah: false)
|
|
#defineDeclsWithKnownNames()
|
|
}
|
|
// CHECK: MyIntTwo8
|
|
print(Foo2.MyIntTwo8.self)
|
|
// CHECK: MyIntTwo16
|
|
print(Foo2.MyIntTwo16.self)
|
|
// CHECK: MyIntTwo32
|
|
print(Foo2.MyIntTwo32.self)
|
|
// CHECK: MyIntTwo64
|
|
print(Foo2.MyIntTwo64.self)
|
|
// CHECK: A
|
|
print(Foo2.A.self)
|
|
// CHECK: B
|
|
print(Foo2.B.self)
|
|
// CHECK: 1
|
|
print(Foo2().foo)
|
|
// CHECK: 2
|
|
print(Foo2().addOne(1))
|
|
|
|
#if TEST_DIAGNOSTICS
|
|
struct Foo3 {
|
|
#bitwidthNumberedStructs("BUG", blah: false)
|
|
// expected-note@-1 4{{in expansion of macro 'bitwidthNumberedStructs' here}}
|
|
// CHECK-DIAGS: CONTENTS OF FILE @__swiftmacro_9MacroUser016testFreestandingA9ExpansionyyF4Foo3L_V23bitwidthNumberedStructsfMf0_.swift
|
|
// CHECK-DIAGS: struct BUG {
|
|
// CHECK-DIAGS: func $s9MacroUser016testFreestandingA9ExpansionyyF4Foo3L_V23bitwidthNumberedStructsfMf0_6methodfMu_()
|
|
// CHECK-DIAGS: func $s9MacroUser016testFreestandingA9ExpansionyyF4Foo3L_V23bitwidthNumberedStructsfMf0_6methodfMu0{{_?}}()
|
|
}
|
|
#endif
|
|
|
|
// FIXME: Declaration macro expansions in BraceStmt don't work yet.
|
|
// HECK: MyIntGlobal8
|
|
// print(MyIntGlobal8.self)
|
|
// HECK: MyIntGlobal16
|
|
// print(MyIntGlobal16.self)
|
|
// HECK: MyIntGlobal32
|
|
// print(MyIntGlobal32.self)
|
|
// HECK: MyIntGlobal64
|
|
// print(MyIntGlobal64.self)
|
|
}
|
|
testFreestandingMacroExpansion()
|