Require `StaticString` argument + fix string literal issues
We probably don't want something like this to succeed:
let worldString = "world"
let hello = #ObfuscatedString("Hello, \(worldString)!")
print(hello) // prints "Hello, \(worldString)!"
With the change in this PR, you'll now get an error: "The provided string must be static."
In the future, we could probably do some magic to actually make string interpolation work. But in the meantime, let's at least make the expansion error out.
Thank you.
Certainly, if a non-static string was given, an error occurred when the macro was expanded.
Failed to receive result from plugin (from macro 'ObfuscatedString')
In the fifth line below, I thought it would be possible to prevent this by using StaticString instead of String.
https://github.com/p-x9/ObfuscateMacro/blob/e4d48e8217fac8fcd57dd0f4b776475c3e84db0a/Sources/ObfuscateMacro/ObfuscateMacro.swift#L4-L8
However, it is good to have handling both on the ObfuscateMacroPlugin side and on the ObfuscateMacro side.
I'm not super familiar with Swift Macros yet (this is the first one I've really looked at).
In the Swift guide they don't seem to use StaticString as the argument type in their example "FourCharacterCode" macro. In the Implementing a Macro section search for "Need a static string" - I took inspiration from that.
I'll change it to StaticString for now - can always be changed back if we figure out how to do string interpolation.
I've decided to incorporate the string literal handling of swift-macro-toolkit to make the string literal interpretation more robust. Escape characters like "\u{2020}" were being incorrectly interpreted as literals on main.
OK I believe I am actually done with this PR now, if you want to take a look.
@p-x9 let me know what you think. Just to be clear, the current behavior of the macro is that it will interpret string interpolation as a literal and not fail.
let someVar = "you won't see this"
let result = #ObfuscatedString("Take a look: \(someVar)")
print(result)
On main, compilation will succeed (it should fail) and you'll get as print output: Take a look: \(someVar).
Additionally,
print(#ObfuscatedString("\u{2021}"))
On main, will output: \u{2021} instead of the correct ‡
The behaviour in the main branch is as you say and this should fail at compile time.
the current behavior of the macro is that it will interpret string interpolation as a literal and not fail. let someVar = "you won't see this" let result = #ObfuscatedString("Take a look: (someVar)") print(result)
I was not aware of the issue of escaping charactors not being handled correctly. Thank you for finding it.
Additionally, print(#ObfuscatedString("\u{2021}")) On main, will output: \u{2021} instead of the correct ‡
Since the equality "\u{2021}" == "‡" holds in Swift, the following equality should also hold.
#ObfuscatedString("\u{2021}") == #ObfuscatedString("‡")
Therefore I agree with your fixes.
Any chance you'll pull this in anytime soon? @p-x9
turns out there was a way in SwiftParser to handle the string literals correctly, so I've removed the swift-macro-toolkit dependency. Hopefully that makes things a lot cleaner!
Thank you. I did not know such a feature had been added to swift-syntax.
If there are no additional changes, I will Merge and Release as is, is that ok?
Yes this PR is finished! Yes, please tag a new release too.
I appreciate your many fixes.