I'm trying to create a macro that adds the file and line to a string that I use with OSLog. However, I only get warnings that either the String is not in the format of OSLogMessage or not an interpolated string. The Macro looks like this at the moment:
public struct LocMacro: ExpressionMacro {
public static func expansion(
of node: some FreestandingMacroExpansionSyntax,
in context: some MacroExpansionContext
) -> ExprSyntax {
guard let argument = node.argumentList.first?.expression.as(StringLiteralExprSyntax.self)?.segments else {
fatalError("compiler bug: the macro does not have any StringLiteralExprSyntax arguments.")
}
guard let file = context.location(of: node)?.file.as(StringLiteralExprSyntax.self)?.segments,
let line = context.location(of: node)?.line.as(IntegerLiteralExprSyntax.self) else {
fatalError("compiler bug: the macro is unable to retrieve file and line numbers")
}
return "\"\(argument) - \(file):\(line)\""
}
}
and here the exposed macro:
@freestanding(expression)
public macro loc(_ text: String) -> String = #externalMacro(module: "LxoMacrosMacros", type: "LocMacro")
I want to use it like this:
import LxoMacros
import OSLog
let logger = Logger()
let someNumber = 17
logger.debug(#loc("Working with some number \(someNumber)"))
which should expand to:
logger.debug("Working with some number \(someNumber) - MyFile.swift:8")
Is there a way to change the macro so that it returns the correct type? When expending the macro it does show the right string, which works with print()
and so on, but assuming since the Logger uses some sort of compiler check as well, it doesn't seem to work together as expected.