From 6739ba53a7d91a0288d5d3887cee4a2ec15a5a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20G=C3=BCnd=C3=BCz?= Date: Wed, 14 Oct 2026 09:13:08 +0200 Subject: [PATCH] Name the case where a catalog key holds a property name The guide said properties never contribute to a macro key. The macro did append property names, but most compiler versions never passed the enclosing property to it. A catalog extracted with a toolchain that did holds keys such as BookmarkManager.BookmarkError.UserFriendlyMessage.theURLIsNotAValidFileURL, seen in a real app migration. The guide now names that case and says the catalog key wins. --- MigrationGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/MigrationGuide.md b/MigrationGuide.md index 1745353..730ab6a 100644 --- a/MigrationGuide.md +++ b/MigrationGuide.md @@ -61,6 +61,7 @@ Walk from the OUTERMOST enclosing declaration to the innermost one around the ma - `struct`, `class` and `enum` declarations contribute their name; `extension` contributes the extended type (`extension TK.Label` contributes `TK.Label` i.e. two components `TK`, `Label`; `extension Foo.Bar` contributes `Foo`, `Bar`). `actor`, `protocol`, closures, accessors (`get`/`set`/`didSet`), subscripts and enum cases contribute NOTHING. - A function (`func fetchData(…)`) contributes its base name only (no parameters). An initializer contributes the literal `init`. - Properties contribute NOTHING, stored or computed, and neither does `var body`: a call inside `var body` or `var displayName` gets only the type names before it (`struct SettingsView { var body … #tk("Save Changes") }` → `SettingsView.saveChanges`, `enum Category { var displayName … #tk("Anime") }` → `Category.anime`). Only functions and initializers add a component. +- Exception – a catalog may still contain the property name: the macro itself did append property names, but most compiler versions never handed them to it. A catalog extracted with a toolchain that did contains keys like `BookmarkManager.BookmarkError.UserFriendlyMessage.theURLIsNotAValidFileURL` for a call inside `var userFriendlyMessage`, while an older extraction of the same source holds `BookmarkManager.BookmarkError.theURLIsNotAValidFileURL`. Whatever the catalog holds is the key; if both forms exist, use the one that has translations. - Every contributed name is converted to UpperCamelCase: first letter uppercased, other letters unchanged (`fetchData` → `FetchData`, `RESTClient` stays `RESTClient`); non-alphanumeric characters (including apostrophes) are removed and the following letter is uppercased; diacritics are removed. - Inside the body of a `#Preview { … }` (or any other macro that wraps the code) the context is a long machine-generated name such as `S3App0025BoardFieldViewswift…Ll7PreviewfMf15…`. This cannot be derived by hand – take such a key verbatim from the catalog by matching its last component, and leave the call unchanged if the catalog has no match. - Nested types appear in order, e.g. `struct Outer { struct Inner { func render() { … } } }` → `Outer.Inner.Render`. Closures and `Text(…)`/`Button(…)` nesting do not add components.