Description
Description
I am currently writing a freestanding macro using version 600.0.1
which needs to read some information about its enclosing code. According to this thread on the forums @DougGregor has implemented exactly what I need in #1554 inside the lexicalContext
property. But when I call context.lexicalContext
I always get an empty array, even though my freestanding macro is placed inside a SwiftUI body
within a Button
initializer like this:
import SwiftUI
struct MyView: View {
var body: some View {
Button(#tk("Save Changes")) {
self.handleSave()
}
}
}
The purpose of my macro is to auto-generate a semantic localization key based on the context. The expected expansion:
import SwiftUI
struct MyView: View {
var body: some View {
Button(String(localized: "MyView.Body.Button.saveChanges", defaultValue: "Save Changes")) {
self.handleSave()
}
}
}
I got everything working, except that I can't access the context. I would expect lexicalContext
to be something like ["Button", "body", "MyView"]
or at least contain these texts in some kind of structure so I can read them out. But it's completely empty for me. Am I missing something?
Steps to Reproduce
This is the helper function in my ExpressionMacro
I'm trying to implement:
/// Returns `MyView.body.Button.SaveChanges` for the following view:
/// ```swift
/// struct MyView: View {
/// var body: some View {
/// Button(#tk("Save Changes")) {
/// self.handleSave()
/// }
/// }
/// }
/// ```
/// Or `MyModel.DisplayName.Movie.movie` and `MyModel.DisplayName.Series.tvShow` for the following model:
/// ```swift
/// enum MyModel: String, CaseIterable, Codable {
/// case movie
/// case series
///
/// var displayName: String {
/// switch self {
/// case .movie: #tk("Movie")
/// case .series: #tk("TV Show")
/// }
/// }
/// }
/// ```
/// - NOTE: Use https://swift-ast-explorer.com for development.
private static func semanticKey(
of node: some FreestandingMacroExpansionSyntax,
in context: some MacroExpansionContext
) -> String {
// node-based approach
return node.parent?.description ?? "N/A" // always returns `"N/A"`
// context-based approach
return context.lexicalContext.description // always returns `"[]"`
}