Can confirm it doesn't work on macOS, but does on Linux. Most servers run on Linux so I don't see a problem using it for now.
I wouldn't need to do this if I had the declared types' syntactic representation (or unstripped declaration lexical context) for the macro arguments, which is known at compile time and to the macro expansion where it is expanded (type-safety is enforced, so we know without a doubt at compile time, in my example below, that Shrek.isLove.rawValue
is ExpressibleByStringLiteral
.
The problem as a real-world example
@freestanding(expression)
public macro html<T: ExpressibleByStringLiteral>(attributes: [HTMLElementAttribute] = [], xmlns: T? = nil, _ innerHTML: T...) -> T
HTMLElementAttribute
in question
public enum HTMLElementAttribute {
case title((any ExpressibleByStringLiteral)? = nil)
}
- Problem (I want
StaticString
)
extension InterpolationTests {
enum Shrek : String {
case isLove, isLife
}
@Test func third_party_enum() {
var string:String = #html(attributes: [.title(Shrek.isLove.rawValue)]) // allowed, but runtime required
#expect(string == "<!DOCTYPE html><html title=\"isLove\"></html>")
// my current solution
var staticString:StaticString = #html(lookupFiles: ["/path/where/shrek/declaration/is.swift", "/path/to/referenced/declaration/in/another/file.swift"], attributes: [.title(Shrek.isLove.rawValue)])
#expect(staticString.description == "<!DOCTYPE html><html title=\"isLove\"></html>")
}
}
My solution using SwiftParser
(and looking up files) works, albeit only on Linux/non-macOS, in which it replaces Shrek.isLove.rawValue
with "isLove"
. This is perfect for a server environment that compiles it down to a StaticString
for better performance. A real world example of this would be for a web server serving static web pages where the Shrek.isLove
is accessed throughout the project.
I also have a Localization system written in Swift that returns a StaticString
based on the input language for a certain text. Plugging in the localized StaticString
in the html macro is currently impossible without converting it to a String
at runtime or using my solution.
In my real-world example, and in the project where the problem originates, I use freestanding macros. Having a build tool plugin and attached macros would not fix this problem, at least at first thought.