Skip to content

docs(emitters): reserve Kotlin's facades and Kotlin-word names - #1502

Open
OmarAlJarrah wants to merge 1 commit into
mainfrom
docs/emitters-kotlin-export-names
Open

OmarAlJarrah wants to merge 1 commit into
mainfrom
docs/emitters-kotlin-export-names

Conversation

@OmarAlJarrah

Copy link
Copy Markdown
Member

Summary

#1335 stated Kotlin's reserved sets for the units and for a unit. Each set missed a kind of name that the target or its export gives a class of its own, and one sentence claimed more than holds.

File facades. kotlinc compiles a file's top-level functions and properties into a class named for the file, UserKt for User.kt. A spec class UserKt in the same package failed the JVM build (Duplicate JVM class name 'p/UserKt' generated from: UserKt, UserKt), whether the file held a function or a property. With a function, the Multiplatform export renamed the file's class UserKt_. A unit's set in targets/kotlin/naming.md now holds the class of each file that has a top-level function or property. The Objective-C bullet already reserves every name the target declares in every unit, and that now covers facades too: the export merges same-named files' facades from different packages into one class.

Names whose first word is Kotlin. The export puts Kotlin before the Swift names of its own classes (KotlinBase, KotlinInt). It does the same, in both Objective-C and Swift, for each standard-library class the framework reaches (ProbeKotlinThrowable, KotlinThrowable). #1335 listed only the Objective-C names of the export's own classes (Base, Number, Int).

  • A spec class KotlinInt linked, but a Swift caller's let b: KotlinInt? = Client().boxed() failed: 'KotlinInt' is ambiguous for type lookup in this context.
  • With a spec class KotlinThrowable, the export renamed the standard library's class KotlinThrowable_. A caller's e.kotlinException as? KotlinThrowable was nil for the exception the SDK threw, and as? KotlinThrowable_ matched.
  • A spec class KotlinEnum kept its name until the SDK declared an enum. The enum brought the standard library's KotlinEnum in, and the spec's class became KotlinEnum_.

The set of standard-library classes the framework reaches grows with what the spec declares. So every name whose first word is Kotlin is now reserved among the Swift names, rather than a list, and adding a declaration moves no Swift name. swift.md records the measurements, and T-19 holds the header and a Swift caller to the rule.

Package casing. naming.md said no two units differ in letter case alone. That holds for groups, whose words the package rule lowercases. It does not hold for partition names the options give, since no rule cases those. The paragraph now scopes the claim to groups and points at #1491 for partitions.

Out of scope, filed: #1501. Inside a model or union, a class the target nests (a variant, Unknown, Builder, Companion) hides any class of its name. On the golden spec, 2,971 union variants in 843 unions are named after the type they wrap. The imports section of naming.md points there.

Test plan

  • Probes with Kotlin 2.4.0, Gradle 9.8.2, Corretto 25 and Swift 6.2.3 on darwin/arm64, all offline:
    • JVM: a class UserKt beside a top-level function in User.kt fails with the duplicate-class error above, and so does one beside a top-level property.
    • Multiplatform: with a spec UserKt, the facade exports as UserKt_. Two packages' User.kt facades export as one UserKt class holding both functions.
    • Multiplatform: spec classes KotlinInt, KotlinBase, KotlinThrowable, KotlinException, KotlinUnit and KotlinEnum all link. The header gives KotlinInt the boxed class's Swift name, renames the standard library's Throwable and Exception KotlinThrowable_ and KotlinException_, and renames the spec's KotlinBase and KotlinEnum KotlinBase_ and KotlinEnum_. Without spec classes of those names, the standard library's are ProbeKotlinThrowable and ProbeKotlinException (KotlinThrowable, KotlinException in Swift). Without an enum, the spec's KotlinEnum keeps its name.
    • Swift: let b: KotlinInt? = Client().boxed() fails as quoted. A built and run caller prints false for as? KotlinThrowable and true for as? KotlinThrowable_ on an IllegalStateException the SDK throws.
    • The word grammar drops superscript digits (COM¹ → com, Lpt² → lpt), so "com or lpt with a digit" needs no superscript case.
  • CI: the documents' tests.

Kotlin's reserved sets missed two kinds of name that the target and
its export give classes of their own.

kotlinc compiles a file's top-level functions and properties into a
class named for the file, UserKt for User.kt, so a spec class UserKt
in the same package fails the JVM build ("Duplicate JVM class name
'p/UserKt'"), and the Multiplatform export renames the file's class
UserKt_. A unit's set now holds each such class.

In Swift the export puts "Kotlin" before the names of its own classes
(KotlinBase, KotlinInt) and of each standard-library class the
framework reaches (KotlinThrowable, KotlinEnum). A spec class
KotlinInt made the boxed KotlinInt ambiguous for a Swift caller. One
named KotlinThrowable took the standard library's Swift name, leaving
it KotlinThrowable_, so a caller's `as? KotlinThrowable` no longer
matched a thrown exception. One named KotlinEnum kept its name only
until the spec declared an enum. Every name whose first word is Kotlin
is now reserved among the Swift names, rather than a list that a
declaration the spec adds could grow, and T-19 holds the header to it.

The package-casing paragraph said no two units differ in letter case
alone, which holds for groups but not for partition names the options
give, since no rule cases those; it now says so and points at #1491.
The imports section points at #1501, which covers a class the target
nests in a model or union hiding a class of its name inside it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant