Skip to content

Commit

Permalink
extend print macros
Browse files Browse the repository at this point in the history
  • Loading branch information
maerki committed Sep 12, 2024
1 parent 0fc590d commit b9a26db
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 21 deletions.
1 change: 1 addition & 0 deletions Sources/UBFoundation/Globals/GlobalLogging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import os.log
private var loggerGroup: UBLoggerGroup = UBLoggerGroup()

/// A domain for framework logging manipulation
@available(*, message: "Use #print or OS.Logger instead")

This comment has been minimized.

Copy link
@ubfelix

ubfelix Sep 12, 2024

Contributor

Ist sicher gut, wenn ich mich nicht täusche, haben wir das aber auf dem Swift-6 Branch sowieso alles entfernt.

public enum UBLogging {
/// Sets the global log level for all framework loggers
///
Expand Down
1 change: 1 addition & 0 deletions Sources/UBFoundation/Logging/Logger+Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation

/// Errors thrown by the localization
@available(*, message: "Use #print or OS.Logger instead")
public enum UBLoggingError: Error {
/// The bundle identifier is not found
case bundelIdentifierNotFound
Expand Down
2 changes: 2 additions & 0 deletions Sources/UBFoundation/Logging/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import Foundation
import os.log

@available(*, message: "Use #print or OS.Logger instead")
public protocol UBLoggerListener: AnyObject {
func log(message: String)
}

/// A logger wrapper for the OSLog that provide an easy way to log. The UBLogger is thread safe.
@available(*, message: "Use #print or OS.Logger instead")
public class UBLogger {
/// The logger to use
private let logger: OSLog
Expand Down
1 change: 1 addition & 0 deletions Sources/UBFoundation/Logging/LoggerGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import Foundation

/// A group of loggers. The UBLoggerGroup is thread safe
@available(*, message: "Use #print or OS.Logger instead")
public class UBLoggerGroup {
/// The backing data of the group
private var _loggers: [UBLogger]
Expand Down
22 changes: 22 additions & 0 deletions Sources/UBFoundation/Logging/LoggingMacros+Shadowing.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// LoggingMacros+Shadowing.swift
// UBKit
//
// Created by Nicolas Märki on 12.09.2024.
//

@available(*, message: "Use #print instead")
public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
Swift.print(items, separator: separator, terminator: terminator)
}

@available(*, message: "Use #assert instead")
public func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line) {
Swift.assert(condition(), message(), file: file, line: line)
}

@available(*, message: "Use #assertionFailure instead")
public func assertionFailure(_ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line) {
Swift.assertionFailure(message(), file: file, line: line)
}

Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,32 @@
import Foundation
import os

#if DEBUG
@available(iOS 14.0, *)
@freestanding(expression)
public macro print(_ message: OSLogMessage) = #externalMacro(
module: "UBMacros",
type: "UBPrintMacroDebug"
type: "UBPrintMacro"
)
#else

@available(iOS 14.0, *)
@freestanding(expression)
public macro print(_ message: OSLogMessage) = #externalMacro(
public macro printError(_ message: String) = #externalMacro(
module: "UBMacros",
type: "UBPrintMacroRelease"
type: "UBPrintErrorMacro"
)
#endif

@available(iOS 14.0, *)
@freestanding(expression)
public macro printError(_ message: String) = #externalMacro(
public macro assert(_ condition: Bool, _ message: @autoclosure () -> String = String()) = #externalMacro(
module: "UBMacros",
type: "UBPrintErrorMacro"
type: "UBAssertMacro"
)

@available(iOS 14.0, *)
@freestanding(expression)
public macro assertionFailure(_ message: @autoclosure () -> String = String()) = #externalMacro(
module: "UBMacros",
type: "UBAssertionFailureMacro"
)

@available(iOS 14.0, *)
Expand Down
7 changes: 4 additions & 3 deletions Sources/UBMacros/UBMacroPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import SwiftSyntaxMacros
struct UBMacroPlugin: CompilerPlugin {
let providingMacros: [Macro.Type] = [
URLMacro.self,
UBPrintMacroDebug.self,
UBPrintMacroRelease.self,
UBPrintErrorMacro.self
UBPrintMacro.self,
UBPrintErrorMacro.self,
UBAssertMacro.self,
UBAssertionFailureMacro.self
]
}
67 changes: 59 additions & 8 deletions Sources/UBMacros/UBPrintMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,82 @@ import SwiftSyntaxMacros
import SwiftParser
import os

public struct UBPrintMacroDebug: ExpressionMacro {
public struct UBPrintMacro: ExpressionMacro {
public static func expansion<Node, Context>(of node: Node, in context: Context) throws -> ExprSyntax where Node : FreestandingMacroExpansionSyntax, Context : MacroExpansionContext {

guard let firstArgument = node.argumentList.first?.expression else {
#if DEBUG
guard node.argumentList.count == 1, let firstArgument = node.argumentList.first?.expression else {
throw CustomError.message("Expected a single argument for #print")
}
return "UBPrintMacro.Logger.debug(\(firstArgument))"
#elseif RELEASE
return "UBPrintMacro.noop()"
#else
throw CustomError.message("Neither DEBUG or RELEASE is defined.")
#endif
}
}

public struct UBPrintMacroRelease: ExpressionMacro {
public struct UBPrintErrorMacro: ExpressionMacro {
public static func expansion<Node, Context>(of node: Node, in context: Context) throws -> ExprSyntax where Node : FreestandingMacroExpansionSyntax, Context : MacroExpansionContext {

return "UBPrintMacro.noop()"
guard node.argumentList.count == 1, let firstArgument = node.argumentList.first?.expression else {
throw CustomError.message("Expected a single argument for #printError")
}
return "{UBPrintMacro.Logger.critical(\(firstArgument))\nUBPrintMacro.sendError(\(firstArgument))}()"

}
}

public struct UBPrintErrorMacro: ExpressionMacro {
public struct UBAssertMacro: ExpressionMacro {
public static func expansion<Node, Context>(of node: Node, in context: Context) throws -> ExprSyntax where Node : FreestandingMacroExpansionSyntax, Context : MacroExpansionContext {

guard let firstArgument = node.argumentList.first?.expression else {
throw CustomError.message("Expected a single argument for #print")
guard let firstArgument = node.argumentList.first?.expression
else {
throw CustomError.message("Expected at least one argument for #assert")
}
if node.argumentList.count > 1, let secondArgument = node.argumentList.last?.expression {
#if DEBUG
return "{if !(\(firstArgument)) { UBPrintMacro.Logger.critical(\"Assertion failed: \\(\(secondArgument))\")\nSwift.assertionFailure() }}()"
#elseif RELEASE
return "{if !(\(firstArgument)) { UBPrintMacro.Logger.critical(\"Assertion failed: \\(\(secondArgument))\")\nUBPrintMacro.sendError(\"Assertion failed: \" + \(secondArgument)) }}()"
#else
throw CustomError.message("Neither DEBUG or RELEASE is defined.")
#endif
}
else {
#if DEBUG
return "{if !(\(firstArgument)) { UBPrintMacro.Logger.critical(\"Assertion failed.\")\nSwift.assertionFailure() }}()"
#elseif RELEASE
return "{if !(\(firstArgument)) { UBPrintMacro.Logger.critical(\"Assertion failed.\")\nUBPrintMacro.sendError(\"Assertion failed. \") }}()"
#else
throw CustomError.message("Neither DEBUG or RELEASE is defined.")
#endif
}
}
}

public struct UBAssertionFailureMacro: ExpressionMacro {
public static func expansion<Node, Context>(of node: Node, in context: Context) throws -> ExprSyntax where Node : FreestandingMacroExpansionSyntax, Context : MacroExpansionContext {

if let firstArgument = node.argumentList.first?.expression {
#if DEBUG
return "{UBPrintMacro.Logger.critical(\"Assertion failed: \\(\(firstArgument))\")\nSwift.assertionFailure() }()"
#elseif RELEASE
return "{UBPrintMacro.Logger.critical(\"Assertion failed: \\(\(firstArgument))\")\nUBPrintMacro.sendError(\"Assertion failed: \" + \(firstArgument)) }()"
#else
throw CustomError.message("Neither DEBUG or RELEASE is defined.")
#endif
}
else {
#if DEBUG
return "{UBPrintMacro.Logger.critical(\"Assertion failed.)\")\nSwift.assertionFailure() }()"
#elseif RELEASE
return "{UBPrintMacro.Logger.critical(\"Assertion failed.\")\nUBPrintMacro.sendError(\"Assertion failed.\") }()"
#else
throw CustomError.message("Neither DEBUG or RELEASE is defined.")
#endif
}
return "{UBPrintMacro.Logger.critical(\(firstArgument))\nUBPrintMacro.sendError(\(firstArgument))}()"

}
}
41 changes: 39 additions & 2 deletions Tests/UBFoundationTests/Logging/MacroTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,44 @@ class MacroTests: XCTestCase {
}

func testError() {
var obe = "Hello"
#printError("Failed to not fail \(obe)")
let exp = expectation(description: "Failed")
UBNonFatalErrorReporter.handler = { _ in
exp.fulfill()
}

#printError("Failed to not fail")

wait(for: [exp])
}

func testAssertTrue() {
#assert(true, "Test")
#assert(true)
}

func testAssertFalse() {
let exp = expectation(description: "Failed")
UBNonFatalErrorReporter.handler = { _ in
exp.fulfill()
}

#assert(false, "Test")

wait(for: [exp])
}

func testAssertionFailure() {
let exp = expectation(description: "Failed")
exp.expectedFulfillmentCount = 2
UBNonFatalErrorReporter.handler = { _ in
exp.fulfill()
}

#assertionFailure("Failed")
#assertionFailure()

wait(for: [exp])
}
}


0 comments on commit b9a26db

Please sign in to comment.