Skip to content

Commit 375b4c2

Browse files
Replace #fileID, #filePath, #line, and #column with a single macro. (#304)
We have a bunch of functions that take separate, defaulted arguments for file ID, column, etc. We'd like to normalize these functions to always take a single `SourceLocation` instance, but until now there hasn't been a way to express such a thing as a default argument without capturing the wrong source location. This PR takes advantage of [SE-0422](https://github.com/apple/swift-evolution/blob/main/proposals/0422-caller-side-default-argument-macro-expression.md) to create a new `#_sourceLocation` macro (name pending API review) that does what we want here. We can't use the obvious `#sourceLocation` because the language already reserves that macro name for an unrelated use. Resolves rdar://121883259. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated. --------- Co-authored-by: Stuart Montgomery <[email protected]>
1 parent 21b13a0 commit 375b4c2

28 files changed

+291
-284
lines changed

Sources/Testing/Expectations/Expectation+Macro.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
@freestanding(expression) public macro expect(
2424
_ condition: Bool,
2525
_ comment: @autoclosure () -> Comment? = nil,
26-
sourceLocation: SourceLocation = SourceLocation()
26+
sourceLocation: SourceLocation = #_sourceLocation
2727
) = #externalMacro(module: "TestingMacros", type: "ExpectMacro")
2828

2929
/// Check that an expectation has passed after a condition has been evaluated
@@ -44,7 +44,7 @@
4444
@freestanding(expression) public macro require(
4545
_ condition: Bool,
4646
_ comment: @autoclosure () -> Comment? = nil,
47-
sourceLocation: SourceLocation = SourceLocation()
47+
sourceLocation: SourceLocation = #_sourceLocation
4848
) = #externalMacro(module: "TestingMacros", type: "RequireMacro")
4949

5050
// MARK: - Optional checking
@@ -68,7 +68,7 @@
6868
@freestanding(expression) public macro require<T>(
6969
_ optionalValue: T?,
7070
_ comment: @autoclosure () -> Comment? = nil,
71-
sourceLocation: SourceLocation = SourceLocation()
71+
sourceLocation: SourceLocation = #_sourceLocation
7272
) -> T = #externalMacro(module: "TestingMacros", type: "RequireMacro")
7373

7474
/// Unwrap an optional boolean value or, if it is `nil`, fail and throw an
@@ -98,7 +98,7 @@
9898
public macro require(
9999
_ optionalValue: Bool?,
100100
_ comment: @autoclosure () -> Comment? = nil,
101-
sourceLocation: SourceLocation = SourceLocation()
101+
sourceLocation: SourceLocation = #_sourceLocation
102102
) -> Bool = #externalMacro(module: "TestingMacros", type: "AmbiguousRequireMacro")
103103

104104
// MARK: - Matching errors by type
@@ -136,7 +136,7 @@ public macro require(
136136
@freestanding(expression) public macro expect<E, R>(
137137
throws errorType: E.Type,
138138
_ comment: @autoclosure () -> Comment? = nil,
139-
sourceLocation: SourceLocation = SourceLocation(),
139+
sourceLocation: SourceLocation = #_sourceLocation,
140140
performing expression: () async throws -> R
141141
) = #externalMacro(module: "TestingMacros", type: "ExpectMacro") where E: Error
142142

@@ -175,7 +175,7 @@ public macro require(
175175
@freestanding(expression) public macro expect<R>(
176176
throws _: Never.Type,
177177
_ comment: @autoclosure () -> Comment? = nil,
178-
sourceLocation: SourceLocation = SourceLocation(),
178+
sourceLocation: SourceLocation = #_sourceLocation,
179179
performing expression: () async throws -> R
180180
) = #externalMacro(module: "TestingMacros", type: "ExpectMacro")
181181

@@ -217,7 +217,7 @@ public macro require(
217217
@freestanding(expression) public macro require<E, R>(
218218
throws errorType: E.Type,
219219
_ comment: @autoclosure () -> Comment? = nil,
220-
sourceLocation: SourceLocation = SourceLocation(),
220+
sourceLocation: SourceLocation = #_sourceLocation,
221221
performing expression: () async throws -> R
222222
) = #externalMacro(module: "TestingMacros", type: "RequireMacro") where E: Error
223223

@@ -236,7 +236,7 @@ public macro require(
236236
@freestanding(expression) public macro require<R>(
237237
throws _: Never.Type,
238238
_ comment: @autoclosure () -> Comment? = nil,
239-
sourceLocation: SourceLocation = SourceLocation(),
239+
sourceLocation: SourceLocation = #_sourceLocation,
240240
performing expression: () async throws -> R
241241
) = #externalMacro(module: "TestingMacros", type: "RequireMacro")
242242

@@ -272,7 +272,7 @@ public macro require(
272272
@freestanding(expression) public macro expect<E, R>(
273273
throws error: E,
274274
_ comment: @autoclosure () -> Comment? = nil,
275-
sourceLocation: SourceLocation = SourceLocation(),
275+
sourceLocation: SourceLocation = #_sourceLocation,
276276
performing expression: () async throws -> R
277277
) = #externalMacro(module: "TestingMacros", type: "ExpectMacro") where E: Error & Equatable
278278

@@ -309,7 +309,7 @@ public macro require(
309309
@freestanding(expression) public macro require<E, R>(
310310
throws error: E,
311311
_ comment: @autoclosure () -> Comment? = nil,
312-
sourceLocation: SourceLocation = SourceLocation(),
312+
sourceLocation: SourceLocation = #_sourceLocation,
313313
performing expression: () async throws -> R
314314
) = #externalMacro(module: "TestingMacros", type: "RequireMacro") where E: Error & Equatable
315315

@@ -352,7 +352,7 @@ public macro require(
352352
/// ``expect(throws:_:sourceLocation:performing:)-5lzjz`` instead.
353353
@freestanding(expression) public macro expect<R>(
354354
_ comment: @autoclosure () -> Comment? = nil,
355-
sourceLocation: SourceLocation = SourceLocation(),
355+
sourceLocation: SourceLocation = #_sourceLocation,
356356
performing expression: () async throws -> R,
357357
throws errorMatcher: (any Error) async throws -> Bool
358358
) = #externalMacro(module: "TestingMacros", type: "ExpectMacro")
@@ -400,7 +400,7 @@ public macro require(
400400
/// this macro. The test will then fail if an error is thrown.
401401
@freestanding(expression) public macro require<R>(
402402
_ comment: @autoclosure () -> Comment? = nil,
403-
sourceLocation: SourceLocation = SourceLocation(),
403+
sourceLocation: SourceLocation = #_sourceLocation,
404404
performing expression: () async throws -> R,
405405
throws errorMatcher: (any Error) async throws -> Bool
406406
) = #externalMacro(module: "TestingMacros", type: "RequireMacro")
@@ -474,7 +474,7 @@ public macro require(
474474
@freestanding(expression) public macro expect(
475475
exitsWith expectedExitCondition: ExitCondition,
476476
_ comment: @autoclosure () -> Comment? = nil,
477-
sourceLocation: SourceLocation = SourceLocation(),
477+
sourceLocation: SourceLocation = #_sourceLocation,
478478
performing expression: @convention(thin) () async throws -> Void
479479
) = #externalMacro(module: "TestingMacros", type: "ExitTestExpectMacro")
480480

@@ -549,6 +549,6 @@ public macro require(
549549
@freestanding(expression) public macro require(
550550
exitsWith expectedExitCondition: ExitCondition,
551551
_ comment: @autoclosure () -> Comment? = nil,
552-
sourceLocation: SourceLocation = SourceLocation(),
552+
sourceLocation: SourceLocation = #_sourceLocation,
553553
performing expression: @convention(thin) () async -> Void
554554
) = #externalMacro(module: "TestingMacros", type: "ExitTestRequireMacro")

Sources/Testing/Issues/Confirmation.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ extension Confirmation {
5555
/// `body` is invoked. The default value of this argument is `1`, indicating
5656
/// that the event should occur exactly once. Pass `0` if the event should
5757
/// _never_ occur when `body` is invoked.
58+
/// - sourceLocation: The source location to which any recorded issues should
59+
/// be attributed.
5860
/// - body: The function to invoke.
5961
///
6062
/// - Returns: Whatever is returned by `body`.
@@ -92,10 +94,7 @@ extension Confirmation {
9294
public func confirmation<R>(
9395
_ comment: Comment? = nil,
9496
expectedCount: Int = 1,
95-
fileID: String = #fileID,
96-
filePath: String = #filePath,
97-
line: Int = #line,
98-
column: Int = #column,
97+
sourceLocation: SourceLocation = #_sourceLocation,
9998
_ body: (Confirmation) async throws -> R
10099
) async rethrows -> R {
101100
let confirmation = Confirmation()
@@ -106,7 +105,7 @@ public func confirmation<R>(
106105
.confirmationMiscounted(actual: actualCount, expected: expectedCount),
107106
comments: Array(comment),
108107
backtrace: .current(),
109-
sourceLocation: SourceLocation(fileID: fileID, filePath: filePath, line: line, column: column)
108+
sourceLocation: sourceLocation
110109
)
111110
}
112111
}

Sources/Testing/Issues/Issue+Recording.swift

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ extension Issue {
9999
///
100100
/// - Parameters:
101101
/// - comment: A comment describing the expectation.
102+
/// - sourceLocation: The source location to which the issue should be
103+
/// attributed.
102104
///
103105
/// - Returns: The issue that was recorded.
104106
///
@@ -107,12 +109,8 @@ extension Issue {
107109
/// or ``require(_:_:sourceLocation:)-5l63q`` macros.)
108110
@discardableResult public static func record(
109111
_ comment: Comment? = nil,
110-
fileID: String = #fileID,
111-
filePath: String = #filePath,
112-
line: Int = #line,
113-
column: Int = #column
112+
sourceLocation: SourceLocation = #_sourceLocation
114113
) -> Self {
115-
let sourceLocation = SourceLocation(fileID: fileID, filePath: filePath, line: line, column: column)
116114
let sourceContext = SourceContext(backtrace: .current(), sourceLocation: sourceLocation)
117115
let issue = Issue(kind: .unconditional, comments: Array(comment), sourceContext: sourceContext)
118116
return issue.record()
@@ -127,6 +125,8 @@ extension Issue {
127125
/// - Parameters:
128126
/// - error: The error that caused the issue.
129127
/// - comment: A comment describing the expectation.
128+
/// - sourceLocation: The source location to which the issue should be
129+
/// attributed.
130130
///
131131
/// - Returns: The issue that was recorded.
132132
///
@@ -137,12 +137,8 @@ extension Issue {
137137
@discardableResult public static func record(
138138
_ error: any Error,
139139
_ comment: Comment? = nil,
140-
fileID: String = #fileID,
141-
filePath: String = #filePath,
142-
line: Int = #line,
143-
column: Int = #column
140+
sourceLocation: SourceLocation = #_sourceLocation
144141
) -> Self {
145-
let sourceLocation = SourceLocation(fileID: fileID, filePath: filePath, line: line, column: column)
146142
let backtrace = Backtrace(forFirstThrowOf: error) ?? Backtrace.current()
147143
let sourceContext = SourceContext(backtrace: backtrace, sourceLocation: sourceLocation)
148144
let issue = Issue(kind: .errorCaught(error), comments: Array(comment), sourceContext: sourceContext)

Sources/Testing/Issues/Issue.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public struct Issue: Sendable {
1313
/// Kinds of issues which may be recorded.
1414
public enum Kind: Sendable {
1515
/// An issue which occurred unconditionally, for example by using
16-
/// ``Issue/record(_:fileID:filePath:line:column:)``.
16+
/// ``Issue/record(_:sourceLocation:)``.
1717
case unconditional
1818

1919
/// An issue due to a failed expectation, such as those produced by
@@ -33,9 +33,9 @@ public struct Issue: Sendable {
3333
/// ``Confirmation/confirm(count:)`` should have been called.
3434
///
3535
/// This issue can occur when calling
36-
/// ``confirmation(_:expectedCount:fileID:filePath:line:column:_:)`` when
37-
/// the confirmation passed to these functions' `body` closures is confirmed
38-
/// too few or too many times.
36+
/// ``confirmation(_:expectedCount:sourceLocation:_:)`` when the
37+
/// confirmation passed to these functions' `body` closures is confirmed too
38+
/// few or too many times.
3939
indirect case confirmationMiscounted(actual: Int, expected: Int)
4040

4141
/// An issue due to an `Error` being thrown by a test function and caught by
@@ -235,7 +235,7 @@ extension Issue.Kind {
235235
@_spi(ForToolsIntegrationOnly)
236236
public enum Snapshot: Sendable, Codable {
237237
/// An issue which occurred unconditionally, for example by using
238-
/// ``Issue/record(_:fileID:filePath:line:column:)``.
238+
/// ``Issue/record(_:sourceLocation:)``.
239239
case unconditional
240240

241241
/// An issue due to a failed expectation, such as those produced by
@@ -255,9 +255,9 @@ extension Issue.Kind {
255255
/// ``Confirmation/confirm(count:)`` should have been called.
256256
///
257257
/// This issue can occur when calling
258-
/// ``confirmation(_:expectedCount:fileID:filePath:line:column:_:)`` when
259-
/// the confirmation passed to these functions' `body` closures is confirmed
260-
/// too few or too many times.
258+
/// ``confirmation(_:expectedCount:sourceLocation:_:)`` when the
259+
/// confirmation passed to these functions' `body` closures is confirmed too
260+
/// few or too many times.
261261
indirect case confirmationMiscounted(actual: Int, expected: Int)
262262

263263
/// An issue due to an `Error` being thrown by a test function and caught by

0 commit comments

Comments
 (0)