From b6881a0e6e0607438b37e04f283b2f158e283913 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Tue, 26 Nov 2024 17:26:08 +0900 Subject: [PATCH 1/5] Revert "fixup! Add the TracingMacros module and the `@Traced` macro" This reverts commit c36625ee379d25fa7905ee2613f5a33c510e8d29. --- Sources/TracingMacros/TracedMacro.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/TracingMacros/TracedMacro.swift b/Sources/TracingMacros/TracedMacro.swift index 2c7423b..5d99c51 100644 --- a/Sources/TracingMacros/TracedMacro.swift +++ b/Sources/TracingMacros/TracedMacro.swift @@ -11,7 +11,7 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// -import ServiceContextModule +@_exported import ServiceContextModule import Tracing /// A span name for a traced operation, either derived from the function name or explicitly specified. From abc267e2d3daeaec6904c8dbe29c39c879c8b54d Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Tue, 26 Nov 2024 17:26:08 +0900 Subject: [PATCH 2/5] Revert "Make the `@Traced` macro take a TracedOperationName" This reverts commit b363f60cc6e9305af986ba41213489751636e25a. --- .../Docs.docc/TracedOperationName.md | 38 ---------- Sources/TracingMacros/Docs.docc/index.md | 1 - Sources/TracingMacros/TracedMacro.swift | 61 +-------------- .../TracedMacro.swift | 17 ++--- Tests/TracingMacrosTests/TracedTests.swift | 76 +------------------ 5 files changed, 9 insertions(+), 184 deletions(-) delete mode 100644 Sources/TracingMacros/Docs.docc/TracedOperationName.md diff --git a/Sources/TracingMacros/Docs.docc/TracedOperationName.md b/Sources/TracingMacros/Docs.docc/TracedOperationName.md deleted file mode 100644 index 2ebbee8..0000000 --- a/Sources/TracingMacros/Docs.docc/TracedOperationName.md +++ /dev/null @@ -1,38 +0,0 @@ -# ``TracingMacros/TracedOperationName`` - -### Examples - -The default behavior is to use the base name of the function, but you can -explicitly specify this as well. This creates a span named `"preheatOven"`: -```swift -@Traced(.baseName) -func preheatOven(temperature: Int) -``` - -You can request the full name of the function as the span name, this -creates a span named `"preheatOven(temperature:)"`: -```swift -@Traced(.fullName) -func preheatOven(temperature: Int) -``` - -And it is also initializable with a string literal for fully custom names, -this creates a span explicitly named `"preheat oven"`: -```swift -@Traced("preheat oven") -func preheatOven(temperature: Int) -``` -And if you need to load an existing string value as a name, you can use -`.string(someString)` to adapt it. - - -## Topics - -### Create Operation Names -- ``baseName`` -- ``fullName`` -- ``string(_:)`` -- ``init(stringLiteral:)`` - -### Convert an Operation Name to a String -- ``operationName(baseName:fullName:)`` diff --git a/Sources/TracingMacros/Docs.docc/index.md b/Sources/TracingMacros/Docs.docc/index.md index d5b4a03..c999535 100644 --- a/Sources/TracingMacros/Docs.docc/index.md +++ b/Sources/TracingMacros/Docs.docc/index.md @@ -15,4 +15,3 @@ to a function and get started. ### Tracing functions - ``Traced(_:context:ofKind:span:)`` -- ``TracedOperationName`` diff --git a/Sources/TracingMacros/TracedMacro.swift b/Sources/TracingMacros/TracedMacro.swift index 5d99c51..b8040cb 100644 --- a/Sources/TracingMacros/TracedMacro.swift +++ b/Sources/TracingMacros/TracedMacro.swift @@ -14,63 +14,6 @@ @_exported import ServiceContextModule import Tracing -/// A span name for a traced operation, either derived from the function name or explicitly specified. -/// -/// When using the ``Traced(_:context:ofKind:span:)`` macro, you can use this to customize the span name. -public struct TracedOperationName: ExpressibleByStringLiteral { - @usableFromInline - let value: Name - - @usableFromInline - enum Name { - case baseName - case fullName - case string(String) - } - - internal init(value: Name) { - self.value = value - } - - /// Use a literal string as an operation name. - public init(stringLiteral: String) { - value = .string(stringLiteral) - } - - /// Use the base name of the attached function. - /// - /// For `func preheatOven(temperature: Int)` this is `"preheatOven"`. - public static let baseName = TracedOperationName(value: .baseName) - - /// Use the full name of the attached function. - /// - /// For `func preheatOven(temperature: Int)` this is `"preheatOven(temperature:)"`. - /// This is provided by the `#function` macro. - public static let fullName = TracedOperationName(value: .fullName) - - /// Use an explicitly specified operation name. - public static func string(_ text: String) -> Self { - .init(value: .string(text)) - } - - /// Helper logic to support the `Traced` macro turning this operation name into a string. - /// Provided as an inference guide. - /// - /// - Parameters: - /// - baseName: The value to use for the ``baseName`` case. Must be - /// specified explicitly because there's no equivalent of `#function`. - /// - fullName: The value to use for the ``fullName`` case. - @inlinable - @_documentation(visibility: internal) - public static func _getOperationName(_ name: Self, baseName: String, fullName: String = #function) -> String { - switch name.value { - case .baseName: baseName - case .fullName: fullName - case let .string(text): text - } - } -} - #if compiler(>=6.0) /// Instrument a function to place the entire body inside a span. /// @@ -83,13 +26,13 @@ public struct TracedOperationName: ExpressibleByStringLiteral { /// back to the default. /// /// - Parameters: -/// - operationName: The name of the operation being traced. +/// - operationName: The name of the operation being traced. Defaults to the name of the function. /// - context: The `ServiceContext` providing information on where to start the new ``Span``. /// - kind: The ``SpanKind`` of the new ``Span``. /// - spanName: The name of the span variable to introduce in the function. Pass `"_"` to omit it. @attached(body) public macro Traced( - _ operationName: TracedOperationName = .baseName, + _ operationName: String? = nil, context: ServiceContext? = nil, ofKind kind: SpanKind? = nil, span spanName: String = "span" diff --git a/Sources/TracingMacrosImplementation/TracedMacro.swift b/Sources/TracingMacrosImplementation/TracedMacro.swift index 31c699f..2776c9e 100644 --- a/Sources/TracingMacrosImplementation/TracedMacro.swift +++ b/Sources/TracingMacrosImplementation/TracedMacro.swift @@ -31,20 +31,13 @@ public struct TracedMacro: BodyMacro { // Construct a withSpan call matching the invocation of the @Traced macro let (operationName, context, kind, spanName) = try extractArguments(from: node) - let baseNameExpr = ExprSyntax(StringLiteralExprSyntax(content: function.name.text)) var withSpanCall = FunctionCallExprSyntax("withSpan()" as ExprSyntax)! - let operationNameExpr: ExprSyntax - if let operationName { - if operationName.is(StringLiteralExprSyntax.self) { - operationNameExpr = operationName - } else { - operationNameExpr = "TracedOperationName._getOperationName(\(operationName), baseName: \(baseNameExpr))" - } - } else { - operationNameExpr = baseNameExpr - } - withSpanCall.arguments.append(LabeledExprSyntax(expression: operationNameExpr)) + withSpanCall.arguments.append( + LabeledExprSyntax( + expression: operationName ?? ExprSyntax(StringLiteralExprSyntax(content: function.name.text)) + ) + ) func appendComma() { withSpanCall.arguments[withSpanCall.arguments.index(before: withSpanCall.arguments.endIndex)] .trailingComma = .commaToken() diff --git a/Tests/TracingMacrosTests/TracedTests.swift b/Tests/TracingMacrosTests/TracedTests.swift index de6222d..bc0288e 100644 --- a/Tests/TracingMacrosTests/TracedTests.swift +++ b/Tests/TracingMacrosTests/TracedTests.swift @@ -236,7 +236,7 @@ final class TracedMacroTests: XCTestCase { """ let globalName = "example" - @Traced(.string(globalName)) + @Traced(globalName) func example(param: Int) { span.attributes["param"] = param } @@ -244,41 +244,7 @@ final class TracedMacroTests: XCTestCase { expandedSource: """ let globalName = "example" func example(param: Int) { - withSpan(TracedOperationName._getOperationName(.string(globalName), baseName: "example")) { span in - span.attributes["param"] = param - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - - assertMacroExpansion( - """ - @Traced(.baseName) - func useBaseName(param: Int) { - span.attributes["param"] = param - } - """, - expandedSource: """ - func useBaseName(param: Int) { - withSpan(TracedOperationName._getOperationName(.baseName, baseName: "useBaseName")) { span in - span.attributes["param"] = param - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - - assertMacroExpansion( - """ - @Traced(.fullName) - func useFullName(param: Int) { - span.attributes["param"] = param - } - """, - expandedSource: """ - func useFullName(param: Int) { - withSpan(TracedOperationName._getOperationName(.fullName, baseName: "useFullName")) { span in + withSpan(globalName) { span in span.attributes["param"] = param } } @@ -494,47 +460,9 @@ func example(param: Int) { span.attributes["param"] = param } -let globalName = "example" - -@Traced(.string(globalName)) -func withDynamicOperationName(param: Int) { - span.attributes["param"] = param -} - -@Traced(.baseName) -func useBaseName(param: Int) { - span.attributes["param"] = param -} - -@Traced(.fullName) -func useFullName(param: Int) { - span.attributes["param"] = param -} - @Traced("custom span name", context: .topLevel, ofKind: .client, span: "customSpan") func exampleWithParams(span: Int) { customSpan.attributes["span"] = span + 1 } #endif - -extension TracedMacroTests { - func test_operationNameBehavior() { - XCTAssertEqual( - TracedOperationName._getOperationName("example custom", baseName: "test_operationNameBehavior"), - "example custom" - ) - XCTAssertEqual( - TracedOperationName._getOperationName(.string("example literal"), baseName: "test_operationNameBehavior"), - "example literal" - ) - XCTAssertEqual( - TracedOperationName._getOperationName(.baseName, baseName: "test_operationNameBehavior"), - "test_operationNameBehavior" - ) - XCTAssertEqual( - TracedOperationName._getOperationName(.fullName, baseName: "test_operationNameBehavior"), - "test_operationNameBehavior()" - ) - } -} From 9f7da4341013420a238a33dd5510fb7b3526e00d Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Tue, 26 Nov 2024 17:26:08 +0900 Subject: [PATCH 3/5] Revert "Add support for parameters passed to the `@Traced` macro" This reverts commit 148582ed96726ab7155b5c8d25f7eb3392351260. --- Sources/TracingMacros/Docs.docc/index.md | 10 +- Sources/TracingMacros/TracedMacro.swift | 20 +- .../TracedMacro.swift | 81 +------ Tests/TracingMacrosTests/TracedTests.swift | 202 ------------------ 4 files changed, 10 insertions(+), 303 deletions(-) diff --git a/Sources/TracingMacros/Docs.docc/index.md b/Sources/TracingMacros/Docs.docc/index.md index c999535..948e219 100644 --- a/Sources/TracingMacros/Docs.docc/index.md +++ b/Sources/TracingMacros/Docs.docc/index.md @@ -6,12 +6,12 @@ Macro helpers for Tracing. The TracingMacros module provides optional macros to make it easier to write traced code. -The ``Traced(_:context:ofKind:span:)`` macro lets you avoid the extra -indentation that comes with adopting traced code, and avoids having to keep the -throws/try and async/await in-sync with the body. You can just attach `@Traced` -to a function and get started. +The ``Traced()`` macro lets you avoid the extra indentation that comes with +adopting traced code, and avoids having to keep the throws/try and async/await +in-sync with the body. You can just attach `@Traced` to a function and get +started. ## Topics ### Tracing functions -- ``Traced(_:context:ofKind:span:)`` +- ``Traced()`` diff --git a/Sources/TracingMacros/TracedMacro.swift b/Sources/TracingMacros/TracedMacro.swift index b8040cb..fcebf5c 100644 --- a/Sources/TracingMacros/TracedMacro.swift +++ b/Sources/TracingMacros/TracedMacro.swift @@ -18,23 +18,7 @@ import Tracing /// Instrument a function to place the entire body inside a span. /// /// This macro is equivalent to calling ``withSpan`` in the body, but saves an -/// indentation level and duplication. It introduces a `span` variable into the -/// body of the function which can be used to add attributes to the span. -/// -/// Parameters are passed directly to ``withSpan`` where applicable, and -/// omitting the parameters from the macro omit them from the call, falling -/// back to the default. -/// -/// - Parameters: -/// - operationName: The name of the operation being traced. Defaults to the name of the function. -/// - context: The `ServiceContext` providing information on where to start the new ``Span``. -/// - kind: The ``SpanKind`` of the new ``Span``. -/// - spanName: The name of the span variable to introduce in the function. Pass `"_"` to omit it. +/// indentation level and duplication. @attached(body) -public macro Traced( - _ operationName: String? = nil, - context: ServiceContext? = nil, - ofKind kind: SpanKind? = nil, - span spanName: String = "span" -) = #externalMacro(module: "TracingMacrosImplementation", type: "TracedMacro") +public macro Traced() = #externalMacro(module: "TracingMacrosImplementation", type: "TracedMacro") #endif diff --git a/Sources/TracingMacrosImplementation/TracedMacro.swift b/Sources/TracingMacrosImplementation/TracedMacro.swift index 2776c9e..d544a9b 100644 --- a/Sources/TracingMacrosImplementation/TracedMacro.swift +++ b/Sources/TracingMacrosImplementation/TracedMacro.swift @@ -30,32 +30,9 @@ public struct TracedMacro: BodyMacro { } // Construct a withSpan call matching the invocation of the @Traced macro - let (operationName, context, kind, spanName) = try extractArguments(from: node) - var withSpanCall = FunctionCallExprSyntax("withSpan()" as ExprSyntax)! - withSpanCall.arguments.append( - LabeledExprSyntax( - expression: operationName ?? ExprSyntax(StringLiteralExprSyntax(content: function.name.text)) - ) - ) - func appendComma() { - withSpanCall.arguments[withSpanCall.arguments.index(before: withSpanCall.arguments.endIndex)] - .trailingComma = .commaToken() - } - if let context { - appendComma() - withSpanCall.arguments.append(LabeledExprSyntax(label: "context", expression: context)) - } - if let kind { - appendComma() - withSpanCall.arguments.append(LabeledExprSyntax(label: "ofKind", expression: kind)) - } - - // Introduce a span identifier in scope - var spanIdentifier: TokenSyntax = "span" - if let spanName { - spanIdentifier = .identifier(spanName) - } + let operationName = StringLiteralExprSyntax(content: function.name.text) + let withSpanCall: ExprSyntax = "withSpan(\(operationName))" // We want to explicitly specify the closure effect specifiers in order // to avoid warnings about unused try/await expressions. @@ -70,7 +47,7 @@ public struct TracedMacro: BodyMacro { throwsClause?.throwsSpecifier = .keyword(.throws) } var withSpanExpr: ExprSyntax = """ - \(withSpanCall) { \(spanIdentifier) \(asyncClause)\(throwsClause)\(returnClause)in \(body.statements) } + \(withSpanCall) { span \(asyncClause)\(throwsClause)\(returnClause)in \(body.statements) } """ // Apply a try / await as necessary to adapt the withSpan expression @@ -85,58 +62,6 @@ public struct TracedMacro: BodyMacro { return ["\(withSpanExpr)"] } - - static func extractArguments( - from node: AttributeSyntax - ) throws -> ( - operationName: ExprSyntax?, - context: ExprSyntax?, - kind: ExprSyntax?, - spanName: String? - ) { - // If there are no arguments, we don't have to do any of these bindings - guard let arguments = node.arguments?.as(LabeledExprListSyntax.self) else { - return (nil, nil, nil, nil) - } - - func getArgument(label: String) -> ExprSyntax? { - arguments.first(where: { $0.label?.identifier?.name == label })?.expression - } - - // The operation name is the first argument if it's unlabeled - var operationName: ExprSyntax? - if let firstArgument = arguments.first, firstArgument.label == nil { - operationName = firstArgument.expression - } - - let context = getArgument(label: "context") - let kind = getArgument(label: "ofKind") - var spanName: String? - let spanNameExpr = getArgument(label: "span") - if let spanNameExpr { - guard let stringLiteral = spanNameExpr.as(StringLiteralExprSyntax.self), - stringLiteral.segments.count == 1, - let segment = stringLiteral.segments.first, - let segmentText = segment.as(StringSegmentSyntax.self) - else { - throw MacroExpansionErrorMessage("span name must be a simple string literal") - } - let text = segmentText.content.text - let isValidIdentifier = DeclReferenceExprSyntax("\(raw: text)" as ExprSyntax)?.hasError == false - let isValidWildcard = text == "_" - guard isValidIdentifier || isValidWildcard else { - throw MacroExpansionErrorMessage("'\(text)' is not a valid parameter name") - } - spanName = text - } - return ( - operationName: operationName, - context: context, - kind: kind, - spanName: spanName - ) - } - } #endif diff --git a/Tests/TracingMacrosTests/TracedTests.swift b/Tests/TracingMacrosTests/TracedTests.swift index bc0288e..5871cb7 100644 --- a/Tests/TracingMacrosTests/TracedTests.swift +++ b/Tests/TracingMacrosTests/TracedTests.swift @@ -213,203 +213,6 @@ final class TracedMacroTests: XCTestCase { macros: ["Traced": TracedMacro.self] ) } - - func test_tracedMacro_specifyOperationName() { - assertMacroExpansion( - """ - @Traced("example but with a custom operationName") - func example(param: Int) { - span.attributes["param"] = param - } - """, - expandedSource: """ - func example(param: Int) { - withSpan("example but with a custom operationName") { span in - span.attributes["param"] = param - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - - assertMacroExpansion( - """ - let globalName = "example" - - @Traced(globalName) - func example(param: Int) { - span.attributes["param"] = param - } - """, - expandedSource: """ - let globalName = "example" - func example(param: Int) { - withSpan(globalName) { span in - span.attributes["param"] = param - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_specifyContext() { - assertMacroExpansion( - """ - @Traced(context: .topLevel) - func example() { - print("Hello") - } - """, - expandedSource: """ - func example() { - withSpan("example", context: .topLevel) { span in - print("Hello") - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_specifyKind() { - assertMacroExpansion( - """ - @Traced(ofKind: .client) - func example() { - print("Hello") - } - """, - expandedSource: """ - func example() { - withSpan("example", ofKind: .client) { span in - print("Hello") - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_specifySpanBindingName() { - assertMacroExpansion( - """ - @Traced(span: "customSpan") - func example(span: String) throws { - customSpan.attributes["span"] = span - } - """, - expandedSource: """ - func example(span: String) throws { - try withSpan("example") { customSpan throws in - customSpan.attributes["span"] = span - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - - assertMacroExpansion( - """ - @Traced(span: "_") - func example(span: String) { - print(span) - } - """, - expandedSource: """ - func example(span: String) { - withSpan("example") { _ in - print(span) - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_specifySpanBindingName_invalid() { - assertMacroExpansion( - """ - @Traced(span: 1) - func example(span: String) throws { - customSpan.attributes["span"] = span - } - """, - expandedSource: """ - func example(span: String) throws { - customSpan.attributes["span"] = span - } - """, - diagnostics: [ - .init(message: "span name must be a simple string literal", line: 1, column: 1) - ], - macros: ["Traced": TracedMacro.self] - ) - - assertMacroExpansion( - """ - @Traced(span: "invalid name") - func example(span: String) throws { - customSpan.attributes["span"] = span - } - - @Traced(span: "123") - func example2(span: String) throws { - customSpan.attributes["span"] = span - } - """, - expandedSource: """ - func example(span: String) throws { - customSpan.attributes["span"] = span - } - func example2(span: String) throws { - customSpan.attributes["span"] = span - } - """, - diagnostics: [ - .init(message: "'invalid name' is not a valid parameter name", line: 1, column: 1), - .init(message: "'123' is not a valid parameter name", line: 6, column: 1), - ], - macros: ["Traced": TracedMacro.self] - ) - - assertMacroExpansion( - """ - @Traced(span: "Hello \\(1)") - func example(span: String) throws { - customSpan.attributes["span"] = span - } - """, - expandedSource: """ - func example(span: String) throws { - customSpan.attributes["span"] = span - } - """, - diagnostics: [ - .init(message: "span name must be a simple string literal", line: 1, column: 1) - ], - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_multipleMacroParameters() { - assertMacroExpansion( - """ - @Traced("custom span name", context: .topLevel, ofKind: .client, span: "customSpan") - func example(span: Int) { - customSpan.attributes["span"] = span + 1 - } - """, - expandedSource: """ - func example(span: Int) { - withSpan("custom span name", context: .topLevel, ofKind: .client) { customSpan in - customSpan.attributes["span"] = span + 1 - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } #endif } @@ -460,9 +263,4 @@ func example(param: Int) { span.attributes["param"] = param } -@Traced("custom span name", context: .topLevel, ofKind: .client, span: "customSpan") -func exampleWithParams(span: Int) { - customSpan.attributes["span"] = span + 1 -} - #endif From dd03126221a6dd48f97925c8877d85948e43dd4c Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Tue, 26 Nov 2024 17:26:08 +0900 Subject: [PATCH 4/5] Revert "Support async/throws functions in the `@Traced` macro" This reverts commit daac1d4a10f4dd7c2c178ba7303ba20e53443205. --- Sources/TracingMacros/Docs.docc/index.md | 3 +- .../TracedMacro.swift | 29 +-- Tests/TracingMacrosTests/TracedTests.swift | 173 ------------------ 3 files changed, 2 insertions(+), 203 deletions(-) diff --git a/Sources/TracingMacros/Docs.docc/index.md b/Sources/TracingMacros/Docs.docc/index.md index 948e219..9666935 100644 --- a/Sources/TracingMacros/Docs.docc/index.md +++ b/Sources/TracingMacros/Docs.docc/index.md @@ -7,8 +7,7 @@ Macro helpers for Tracing. The TracingMacros module provides optional macros to make it easier to write traced code. The ``Traced()`` macro lets you avoid the extra indentation that comes with -adopting traced code, and avoids having to keep the throws/try and async/await -in-sync with the body. You can just attach `@Traced` to a function and get +adopting traced code. You can just attach `@Traced` to a function and get started. ## Topics diff --git a/Sources/TracingMacrosImplementation/TracedMacro.swift b/Sources/TracingMacrosImplementation/TracedMacro.swift index d544a9b..120b6e5 100644 --- a/Sources/TracingMacrosImplementation/TracedMacro.swift +++ b/Sources/TracingMacrosImplementation/TracedMacro.swift @@ -29,36 +29,9 @@ public struct TracedMacro: BodyMacro { throw MacroExpansionErrorMessage("expected a function with a body") } - // Construct a withSpan call matching the invocation of the @Traced macro - let operationName = StringLiteralExprSyntax(content: function.name.text) let withSpanCall: ExprSyntax = "withSpan(\(operationName))" - - // We want to explicitly specify the closure effect specifiers in order - // to avoid warnings about unused try/await expressions. - // We might as well explicitly specify the closure return type to help type inference. - - let asyncClause = function.signature.effectSpecifiers?.asyncSpecifier - let returnClause = function.signature.returnClause - var throwsClause = function.signature.effectSpecifiers?.throwsClause - // You aren't allowed to apply "rethrows" as a closure effect - // specifier, so we have to convert this to a "throws" effect - if throwsClause?.throwsSpecifier.tokenKind == .keyword(.rethrows) { - throwsClause?.throwsSpecifier = .keyword(.throws) - } - var withSpanExpr: ExprSyntax = """ - \(withSpanCall) { span \(asyncClause)\(throwsClause)\(returnClause)in \(body.statements) } - """ - - // Apply a try / await as necessary to adapt the withSpan expression - - if function.signature.effectSpecifiers?.asyncSpecifier != nil { - withSpanExpr = "await \(withSpanExpr)" - } - - if function.signature.effectSpecifiers?.throwsClause != nil { - withSpanExpr = "try \(withSpanExpr)" - } + let withSpanExpr: ExprSyntax = "\(withSpanCall) { span in \(body.statements) }" return ["\(withSpanExpr)"] } diff --git a/Tests/TracingMacrosTests/TracedTests.swift b/Tests/TracingMacrosTests/TracedTests.swift index 5871cb7..6bb339a 100644 --- a/Tests/TracingMacrosTests/TracedTests.swift +++ b/Tests/TracingMacrosTests/TracedTests.swift @@ -55,146 +55,6 @@ final class TracedMacroTests: XCTestCase { ) } - func test_tracedMacro_sync_throws() { - assertMacroExpansion( - """ - @Traced - func syncThrowingExample(param: Int) throws { - struct ExampleError: Error { - } - throw ExampleError() - } - """, - expandedSource: """ - func syncThrowingExample(param: Int) throws { - try withSpan("syncThrowingExample") { span throws in - struct ExampleError: Error { - } - throw ExampleError() - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_sync_rethrows() { - assertMacroExpansion( - """ - @Traced - func syncRethrowingExample(body: () throws -> Int) rethrows -> Int { - print("Starting") - let result = try body() - print("Ending") - return result - } - """, - expandedSource: """ - func syncRethrowingExample(body: () throws -> Int) rethrows -> Int { - try withSpan("syncRethrowingExample") { span throws -> Int in - print("Starting") - let result = try body() - print("Ending") - return result - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_async_nothrow() { - assertMacroExpansion( - """ - @Traced - func asyncNonthrowingExample(param: Int) async { - print(param) - } - """, - expandedSource: """ - func asyncNonthrowingExample(param: Int) async { - await withSpan("asyncNonthrowingExample") { span async in - print(param) - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_async_throws() { - assertMacroExpansion( - """ - @Traced - func asyncThrowingExample(param: Int) async throws { - try await Task.sleep(for: .seconds(1)) - print("Hello") - } - """, - expandedSource: """ - func asyncThrowingExample(param: Int) async throws { - try await withSpan("asyncThrowingExample") { span async throws in - try await Task.sleep(for: .seconds(1)) - print("Hello") - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_async_rethrows() { - assertMacroExpansion( - """ - @Traced - func asyncRethrowingExample(body: () async throws -> Int) async rethrows -> Int { - try? await Task.sleep(for: .seconds(1)) - let result = try await body() - span.attributes["result"] = result - return result - } - """, - expandedSource: """ - func asyncRethrowingExample(body: () async throws -> Int) async rethrows -> Int { - try await withSpan("asyncRethrowingExample") { span async throws -> Int in - try? await Task.sleep(for: .seconds(1)) - let result = try await body() - span.attributes["result"] = result - return result - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - // Testing that this expands correctly, but not including this as a - // compile-test because withSpan doesn't currently support typed throws. - func test_tracedMacro_async_typed_throws() { - assertMacroExpansion( - """ - @Traced - func asyncTypedThrowingExample(body: () async throws(Err) -> Int) async throws(Err) -> Int { - try? await Task.sleep(for: .seconds(1)) - let result = try await body() - span.attributes["result"] = result - return result - } - """, - expandedSource: """ - func asyncTypedThrowingExample(body: () async throws(Err) -> Int) async throws(Err) -> Int { - try await withSpan("asyncTypedThrowingExample") { span async throws(Err) -> Int in - try? await Task.sleep(for: .seconds(1)) - let result = try await body() - span.attributes["result"] = result - return result - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - func test_tracedMacro_accessSpan() { assertMacroExpansion( """ @@ -225,39 +85,6 @@ func syncNonthrowingExample(param: Int) { print(param) } -@Traced -func syncThrowingExample(param: Int) throws { - struct ExampleError: Error {} - throw ExampleError() -} - -@Traced -func syncRethrowingExample(body: () throws -> Int) rethrows -> Int { - print("Starting") - let result = try body() - print("Ending") - return result -} - -@Traced -func asyncNonthrowingExample(param: Int) async { - print(param) -} - -@Traced -func asyncThrowingExample(param: Int) async throws { - try await Task.sleep(for: .seconds(1)) - print("Hello") -} - -@Traced -func asyncRethrowingExample(body: () async throws -> Int) async rethrows -> Int { - try? await Task.sleep(for: .seconds(1)) - let result = try await body() - span.attributes["result"] = result - return result -} - @Traced func example(param: Int) { span.attributes["param"] = param From 08ce64078780c50750c8a3aa2965515c958acb9c Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Tue, 26 Nov 2024 17:26:08 +0900 Subject: [PATCH 5/5] Revert "Add the TracingMacros module and the `@Traced` macro" This reverts commit 8632d7af424cd69ba7e753bb1ab46a46b049a128. --- Package.swift | 35 ------- Sources/TracingMacros/Docs.docc/index.md | 16 ---- Sources/TracingMacros/TracedMacro.swift | 24 ----- .../TracedMacro.swift | 50 ---------- Tests/TracingMacrosTests/TracedTests.swift | 93 ------------------- 5 files changed, 218 deletions(-) delete mode 100644 Sources/TracingMacros/Docs.docc/index.md delete mode 100644 Sources/TracingMacros/TracedMacro.swift delete mode 100644 Sources/TracingMacrosImplementation/TracedMacro.swift delete mode 100644 Tests/TracingMacrosTests/TracedTests.swift diff --git a/Package.swift b/Package.swift index 46f1468..369f097 100644 --- a/Package.swift +++ b/Package.swift @@ -1,5 +1,4 @@ // swift-tools-version:5.9 -import CompilerPluginSupport import PackageDescription let package = Package( @@ -17,16 +16,9 @@ let package = Package( "TracingOpenTelemetrySemanticConventions", ] ), - .library( - name: "TracingMacros", - targets: [ - "TracingMacros", - ] - ), ], dependencies: [ .package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.0.0"), - .package(url: "https://github.com/swiftlang/swift-syntax.git", from: "600.0.0-latest"), ], targets: [ .target( @@ -42,32 +34,5 @@ let package = Package( .product(name: "Tracing", package: "swift-distributed-tracing"), ] ), - - // ==== -------------------------------------------------------------------------------------------------------- - // MARK: TracingMacros - - .target( - name: "TracingMacros", - dependencies: [ - .target(name: "TracingMacrosImplementation"), - .product(name: "Tracing", package: "swift-distributed-tracing"), - ] - ), - .macro( - name: "TracingMacrosImplementation", - dependencies: [ - .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), - .product(name: "SwiftCompilerPlugin", package: "swift-syntax"), - ] - ), - .testTarget( - name: "TracingMacrosTests", - dependencies: [ - .target(name: "TracingMacros"), - .target(name: "TracingMacrosImplementation"), - .product(name: "Tracing", package: "swift-distributed-tracing"), - .product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"), - ] - ), ] ) diff --git a/Sources/TracingMacros/Docs.docc/index.md b/Sources/TracingMacros/Docs.docc/index.md deleted file mode 100644 index 9666935..0000000 --- a/Sources/TracingMacros/Docs.docc/index.md +++ /dev/null @@ -1,16 +0,0 @@ -# ``TracingMacros`` - -Macro helpers for Tracing. - -## Overview - -The TracingMacros module provides optional macros to make it easier to write traced code. - -The ``Traced()`` macro lets you avoid the extra indentation that comes with -adopting traced code. You can just attach `@Traced` to a function and get -started. - -## Topics - -### Tracing functions -- ``Traced()`` diff --git a/Sources/TracingMacros/TracedMacro.swift b/Sources/TracingMacros/TracedMacro.swift deleted file mode 100644 index fcebf5c..0000000 --- a/Sources/TracingMacros/TracedMacro.swift +++ /dev/null @@ -1,24 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Distributed Tracing open source project -// -// Copyright (c) 2020-2024 Apple Inc. and the Swift Distributed Tracing project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Distributed Tracing project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -@_exported import ServiceContextModule -import Tracing - -#if compiler(>=6.0) -/// Instrument a function to place the entire body inside a span. -/// -/// This macro is equivalent to calling ``withSpan`` in the body, but saves an -/// indentation level and duplication. -@attached(body) -public macro Traced() = #externalMacro(module: "TracingMacrosImplementation", type: "TracedMacro") -#endif diff --git a/Sources/TracingMacrosImplementation/TracedMacro.swift b/Sources/TracingMacrosImplementation/TracedMacro.swift deleted file mode 100644 index 120b6e5..0000000 --- a/Sources/TracingMacrosImplementation/TracedMacro.swift +++ /dev/null @@ -1,50 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Distributed Tracing open source project -// -// Copyright (c) 2020-2024 Apple Inc. and the Swift Distributed Tracing project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Distributed Tracing project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -import SwiftCompilerPlugin -import SwiftSyntax -import SwiftSyntaxBuilder -import SwiftSyntaxMacros - -#if compiler(>=6.0) -public struct TracedMacro: BodyMacro { - public static func expansion( - of node: AttributeSyntax, - providingBodyFor declaration: some DeclSyntaxProtocol & WithOptionalCodeBlockSyntax, - in context: some MacroExpansionContext - ) throws -> [CodeBlockItemSyntax] { - guard let function = declaration.as(FunctionDeclSyntax.self), - let body = function.body - else { - throw MacroExpansionErrorMessage("expected a function with a body") - } - - let operationName = StringLiteralExprSyntax(content: function.name.text) - let withSpanCall: ExprSyntax = "withSpan(\(operationName))" - let withSpanExpr: ExprSyntax = "\(withSpanCall) { span in \(body.statements) }" - - return ["\(withSpanExpr)"] - } -} -#endif - -@main -struct TracingMacroPlugin: CompilerPlugin { - #if compiler(>=6.0) - let providingMacros: [Macro.Type] = [ - TracedMacro.self - ] - #else - let providingMacros: [Macro.Type] = [] - #endif -} diff --git a/Tests/TracingMacrosTests/TracedTests.swift b/Tests/TracingMacrosTests/TracedTests.swift deleted file mode 100644 index 6bb339a..0000000 --- a/Tests/TracingMacrosTests/TracedTests.swift +++ /dev/null @@ -1,93 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift Distributed Tracing open source project -// -// Copyright (c) 2020-2024 Apple Inc. and the Swift Distributed Tracing project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift Distributed Tracing project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import SwiftSyntaxMacrosTestSupport -import Tracing -import TracingMacros -import TracingMacrosImplementation -import XCTest - -final class TracedMacroTests: XCTestCase { - #if compiler(>=6.0) - func test_tracedMacro_requires_body() { - assertMacroExpansion( - """ - @Traced - func funcWithoutBody() - """, - expandedSource: """ - func funcWithoutBody() - """, - diagnostics: [ - .init(message: "expected a function with a body", line: 1, column: 1) - ], - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_sync_nothrow() { - assertMacroExpansion( - """ - @Traced - func syncNonthrowingExample(param: Int) { - print(param) - } - """, - expandedSource: """ - func syncNonthrowingExample(param: Int) { - withSpan("syncNonthrowingExample") { span in - print(param) - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - - func test_tracedMacro_accessSpan() { - assertMacroExpansion( - """ - @Traced - func example(param: Int) { - span.attributes["param"] = param - } - """, - expandedSource: """ - func example(param: Int) { - withSpan("example") { span in - span.attributes["param"] = param - } - } - """, - macros: ["Traced": TracedMacro.self] - ) - } - #endif -} - -#if compiler(>=6.0) - -// MARK: Compile tests - -@Traced -func syncNonthrowingExample(param: Int) { - print(param) -} - -@Traced -func example(param: Int) { - span.attributes["param"] = param -} - -#endif