diff --git a/docs/emitters/targets/kotlin/naming.md b/docs/emitters/targets/kotlin/naming.md index d162b29ba..717f85ef7 100644 --- a/docs/emitters/targets/kotlin/naming.md +++ b/docs/emitters/targets/kotlin/naming.md @@ -29,6 +29,11 @@ What each [scope](../../refine/reserved-names.md) reserves in Kotlin: one unit's code happens to write, so adding an operation renames no model. - Each Windows device name above, in any letter case, as the JVM writes a top-level class to a file of its name, `Aux.class`, which Windows refuses whatever the extension. + - The class kotlinc compiles a file's top-level functions and properties into, the file's name + followed by `Kt` (`UserKt` for `User.kt`), for each file of the unit that holds one: a class + `UserKt` beside a top-level function or property in `User.kt` failed the JVM build ("Duplicate + JVM class name 'p/UserKt' generated from: UserKt, UserKt"), and beside a function the framework + exported the file's class as `UserKt_`. - On Multiplatform, in the Objective-C namespace every unit's declarations share, a nested one's name joined to its outer's ([Swift](swift.md)): each name above that the target declares, in every unit; the joined name of each public class the target nests in a type, such as @@ -38,18 +43,22 @@ What each [scope](../../refine/reserved-names.md) reserves in Kotlin: - On Multiplatform, among the Swift names a caller sees: every type name Swift's standard library and Foundation declare, which a Swift caller has in scope, a table of the options version as the naming tables are ([naming policy](../../refine/naming.md)), the target's own names included, so - the runtime's `Optional`, `Duration` and `Decimal` take Swift names of their own; and the - framework's own name, `Swift` and `Foundation`, which a caller writes to qualify a name - (`Probe.Client`). A module a caller imports by choice, such as SwiftUI, reserves nothing, since - a file importing it and the framework qualifies a name the two share. A declaration that meets a - name of this bullet or the last only there keeps its Kotlin name and takes an explicit - Objective-C and Swift name, so no JVM name moves for Swift's sake. + the runtime's `Optional`, `Duration` and `Decimal` take Swift names of their own; every name + whose first word is `Kotlin`, the word the export puts before the Swift name of each class of + its own and of each standard-library class the framework reaches (`KotlinInt`, + `KotlinThrowable`), a set the spec's first enum grows by `KotlinEnum`, so that adding a + declaration moves no Swift name; and the framework's own name, `Swift` and `Foundation`, which a + caller writes to qualify a name (`Probe.Client`). A module a caller imports by choice, such as + SwiftUI, reserves nothing, since a file importing it and the framework qualifies a name the two + share. A declaration that meets a name of this bullet or the last only there keeps its Kotlin + name and takes an explicit Objective-C and Swift name, so no JVM name moves for Swift's sake. - **A type**: `equals`, `hashCode`, `toString`, `Builder` and `Companion`. A unit's package segment is its words in lowercase, joined with no separator (`useraccounts`), as -Go's package names are. So two units whose words break differently render alike and collide ([output -units](../../refine/output-units.md)), and no two differ in letter case alone, which a -case-insensitive file system would make one directory. +Go's package names are. So two groups whose words break differently render alike and collide +([output units](../../refine/output-units.md)), and no two groups differ in letter case alone, which +a case-insensitive file system would make one directory. Two partitions' names, which the options +give and no rule cases, still can (#1491). None of a hard keyword, `kotlin` and `java` is a units name. A hard keyword as a package segment takes the escape below, which kotlinc accepts in a `package` and an `import` alike: every hard @@ -74,4 +83,5 @@ would not set apart, takes a trailing underscore. ## Imports Where a Kotlin file refers to a declaration with the simple name of a class it would import, it -writes that class qualified rather than importing it. +writes that class qualified rather than importing it. How code inside a model or union names a class +hidden by one the target nests there is #1501's. diff --git a/docs/emitters/targets/kotlin/swift.md b/docs/emitters/targets/kotlin/swift.md index 877d69371..bba24afc6 100644 --- a/docs/emitters/targets/kotlin/swift.md +++ b/docs/emitters/targets/kotlin/swift.md @@ -43,6 +43,17 @@ A Multiplatform SDK reaches iOS through the Objective-C export, which shapes the among them, took the same Objective-C name, and the framework failed to link (`Linking globals named 'OBJC_METACLASS_$_ProbeNumber': symbol multiply defined!`). With an explicit `@ObjCName` it linked, so each of these names is reserved ([naming](naming.md#reserved-names)). +- The export's own classes take `Kotlin` before their names in Swift (`KotlinBase`, `KotlinInt`), + and each standard-library class the framework reaches takes it in both languages + (`ProbeKotlinThrowable`, `KotlinThrowable` in Swift). Measured with Kotlin 2.4.0 and Swift 6.2.3, + a spec class `KotlinInt` linked, and a caller's `let b: KotlinInt? = Client().boxed()`, of a + function returning `Int?`, failed (`'KotlinInt' is ambiguous for type lookup in this context`). + With a spec class `KotlinThrowable` the export named the standard library's class + `KotlinThrowable_`, so a caller's `e.kotlinException as? KotlinThrowable` was `nil` for an + exception the SDK threw. A spec class `KotlinEnum` kept its name until the SDK declared an enum, + which brought the standard library's in and renamed the spec's `KotlinEnum_`. So every name whose + first word is `Kotlin` is reserved, not only the names the framework reaches, which a declaration + the spec adds can grow ([naming](naming.md#reserved-names)). - Default arguments do not reach Swift, which is one reason models and request types are built through a builder rather than a constructor with defaults. - An exception reaches Swift only as `@Throws` declares it: any other terminates the app, and a diff --git a/docs/emitters/testing/mandatory-tests.md b/docs/emitters/testing/mandatory-tests.md index 6985626f1..83e4e319d 100644 --- a/docs/emitters/testing/mandatory-tests.md +++ b/docs/emitters/testing/mandatory-tests.md @@ -83,8 +83,9 @@ throughout these documents. `wrapper` at the build's root leave every module's sources, no path the build writes, an artifact's or a class file's, has a Windows device name for a segment, and the Multiplatform framework links, its header giving each declaration the Swift name the naming policy chose, none - of them a type Swift's standard library or Foundation declares or a module's name, so a Swift - file that imports the framework and Foundation compiles its uses of both and qualifies a name by + of them a type Swift's standard library or Foundation declares, a module's name or a name whose + first word is `Kotlin`, so a Swift file that imports the framework and Foundation compiles its + uses of both, the export's `KotlinInt` and `KotlinThrowable` among them, and qualifies a name by either module ([Swift](../targets/kotlin/swift.md)). 20. **T-20 · Recursive types** — a model that holds itself directly, through a base, through a tuple and through another model, and one whose cycle passes through a list or a union, generate code