@@ -104,7 +104,7 @@ assigns relative importance to them. Since Kotlin has a big user base, any
104104problem that affects a seemingly minor percentage of users may still affect
105105a large absolute number of people.
106106
107- ** (§ 1) Extending the companion scope** .
107+ ** (# 1 ) Extending the companion scope** .
108108Companion objects are in many ways no different than any other object in Kotlin.
109109In particular, you can write an _ extension_ to a companion object to create
110110a new callable that can be accessed through the classifier's name.
@@ -120,7 +120,7 @@ It's an [old issue](https://youtrack.jetbrains.com/issue/KT-11968) to remove
120120this gate-keeping, and make extending the companion scope available regardless
121121of the presence of an actual companion object class.
122122
123- ** (§ 2) More direct mapping to platform statics.**
123+ ** (# 2 ) More direct mapping to platform statics.**
124124Kotlin prides itself in good interoperability with the underlying platforms
125125it runs. And most of them (JVM, JS, Swift) feature a notion of _ static member_ .
126126In some scenarios, it becomes very important to generate such a static member
@@ -145,13 +145,13 @@ platform well. In many cases, failing to add the corresponding annotation
145145either breaks at runtime, or may succeed to run with unintended behavior
146146(like tests failing or passing when they should not).
147147
148- ** (§ 3) Multiplatform ` @Static ` annotation.**
148+ ** (# 3 ) Multiplatform ` @Static ` annotation.**
149149The current design also require an annotation for every platform
150150(` @JvmStatic ` , ` @JsStatic ` , and so forth). This issue impact authors of
151151multiplatform libraries mostly, that need to remember all those annotations
152152to expose their API in the way expected by every target platform.
153153
154- ** (§ 4) Additional object allocation.**
154+ ** (# 4 ) Additional object allocation.**
155155Since companion objects are indeed objects, they require an allocation the
156156first time they are used. This is a problem in the JVM and Native targets.
157157
@@ -195,7 +195,7 @@ and [dropping the companion if empty](https://youtrack.jetbrains.com/issue/KT-15
195195However, doing so in a naive way impact binary compatibility, since methods
196196or class that were created before would no longer be available.
197197
198- ** (§ 5) No expect/actual matching** .
198+ ** (# 5 ) No expect/actual matching** .
199199Since static members do not exist in the Kotlin language, matching classes
200200in a multiplatform environment becomes more complicated than expected.
201201For example, it may be desirable to declare a expected ` Vector ` type,
@@ -234,7 +234,7 @@ existing features. In the new design we try to follow a few principles:
234234### Companion extensions
235235
236236This is a direct way to declare functions accessible through the type name
237- (that is, class members). This solves problem § 1.
237+ (that is, class members). This solves problem # 1 .
238238
239239``` kotlin
240240companion val Vector .UnitX get() = Vector (1.0 , 0.0 )
@@ -258,7 +258,7 @@ companion extensions define alongside the type itself.
258258
259259### Companion blocks
260260
261- Solving problem § 4 requires changes to the current code generation strategy.
261+ Solving problem # 4 requires changes to the current code generation strategy.
262262In particular, in order to generate code that doesn't allocate a companion
263263object we need to ensure that its instance is not used. We have considered
264264several approaches to this mechanism, ultimately choosing for companion blocks.
@@ -286,7 +286,7 @@ but do not include any of the properties associated with an _object_:
286286
287287The compilation strategy for companion blocks should not be fixed.
288288However, in those platforms that support statics, we propose to use those
289- features, solving § 2 and § 4. This also alleviates the need for § 3,
289+ features, solving # 2 and # 4 . This also alleviates the need for # 3 ,
290290that remains out-of-scope for this KEEP document
291291
292292### Discarded ideas
@@ -408,7 +408,7 @@ reasons for that choice, mostly for the sake of simplicity.
408408- It gives a clear answer to what is in scope and with what priority when
409409 we are in the body of a companion block, companion extension, and companion
410410 object member, by reusing the same machinery (receivers) that we already
411- have in Kotlin (see examples ⌘ 2.1 to ⌘ 2.3).
411+ have in Kotlin (see examples Example 2.1 to Example 2.3).
412412- Companion object members and extensions can always be disambiguated by
413413 _ explicitly_ writing ` T.Companion ` , something that is not possible with
414414 the other kinds of companions.
@@ -440,16 +440,31 @@ confusion especially among experienced Kotlin developers.
440440### Declaration
441441
442442** §1.1** (_ grammar_ ): the [ Kotlin grammar] ( https://kotlinlang.org/spec/syntax-and-grammar.html#syntax-grammar )
443- is modified as follows.
443+ is modified as follows. Note that only function and property declarations are
444+ allowed in a companion block.
444445
445446``` diff
446447 classMemberDeclaration:
447448 ...
448449 | companionObject
449- + | companionDeclaration
450-
451- + companionDeclaration:
452- + 'companion' {NL} classBody
450+ + | companionBlock
451+ +
452+ + companionBlock:
453+ + 'companion' {NL} companionBlockBody
454+ +
455+ + companionBlockBody:
456+ + '{'
457+ + {NL}
458+ + companionBlockDeclarations
459+ + {NL}
460+ + '}'
461+ +
462+ + companionBlockDeclarations:
463+ + {companionBlockDeclaration [semis]}
464+ +
465+ + companionBlockDeclaration:
466+ + functionDeclaration
467+ + | propertyDeclaration
453468
454469 memberModifier
455470 ...
@@ -556,7 +571,7 @@ if desired.
556571are updated to include properties defined in companion blocks or as companion
557572extensions.
558573
559- ** ⌘ 1.1** (_ example_ ): the following code should be accepted. Note that it
574+ ** Example 1.1** (_ example_ ): the following code should be accepted. Note that it
560575uses two separate companion blocks, declares properties with an initializer,
561576and the last one is marked as constant.
562577
@@ -577,7 +592,7 @@ data class Vector(val x: Double, val y: Double) {
577592}
578593```
579594
580- ** ⌘ 1.2** (_ operators_ ): the following code uses ` invoke ` to define
595+ ** Example 1.2** (_ operators_ ): the following code uses ` invoke ` to define
581596a fake constructor that ` suspend ` s.
582597
583598``` kotlin
@@ -642,7 +657,7 @@ object by using its classifier name.
642657** §2.1.2** (_ ` this ` expressions_ ): phantom static implicit ` this ` is not
643658available through [ explicit ` this ` expressions] ( https://kotlinlang.org/spec/overload-resolution.html#receivers ) .
644659Access to companion block members must always be done either implicitly or
645- through an explicit type receiver, as defined in §2.3.
660+ through an explicit type receiver, as defined in §2.3.1.
646661
647662** §2.2.1** (_ companion block members, receiver_ ): the implicit ` this ` receiver
648663for the class is ** not** available for companion block members. As a result,
@@ -672,7 +687,7 @@ The rules are updated as follows (updates in boldface):
672687This approach is consistent with the definition of phantom static ` this ` in the
673688specification as a receiver with more priority than the companion.
674689
675- ** ⌘ 2.1** (_ priority_ ): the code below exemplifies how companion extensions win
690+ ** Example 2.1** (_ priority_ ): the code below exemplifies how companion extensions win
676691even over companion object members, and how to refer to companion object
677692members in such a situation.
678693
@@ -691,7 +706,7 @@ fun example() {
691706}
692707```
693708
694- ** ⌘ 2.2** (_ absence of companion object members in extensions_ ): the code below
709+ ** Example 2.2** (_ absence of companion object members in extensions_ ): the code below
695710exemplifies the fact that companion object members are not available in
696711companion extensions, since they only have the phantom static implicit ` this `
697712as an implicit receiver.
@@ -709,7 +724,7 @@ companion fun Example.example() {
709724}
710725```
711726
712- ** ⌘ 2.4** (_ resolution in companion blocks_ ): the code below exemplifies that
727+ ** Example 2.4** (_ resolution in companion blocks_ ): the code below exemplifies that
713728companion block members and companion block extensions may be called without
714729qualification from any of those places.
715730
@@ -734,7 +749,7 @@ companion fun Example.testInCompanionExtension() {
734749```
735750
736751
737- ** ⌘ 2.4** (_ receiver in companion objects_ ): in the case of members or extensions
752+ ** Example 2.4** (_ receiver in companion objects_ ): in the case of members or extensions
738753to the companion object, the corresponding receiver is introduced with the
739754highest priority. In the case of companion object members, the phantom static
740755implicit ` this ` of the enclosing class is still available.
@@ -782,7 +797,7 @@ The rules are updated as follows (updates in boldface):
782797In the case of a companion extension, the receiver type is not visible in
783798the type of the obtained callable reference.
784799
785- ** ⌘2.4 ** (_ callable references_ ): the code below should be accepted.
800+ ** Example 2.5 ** (_ callable references_ ): the code below should be accepted.
786801
787802``` kotlin
788803data class Vector (val x : Double , val y : Double ) {
@@ -936,7 +951,7 @@ properties are compiled into static private fields.
936951
937952** §4.1 .2 ** (_JVM , companion initialization_): companion initialization is
938953compiled into the static initializer `< clinit> `, following the order described
939- in §3.4 .
954+ in §3.2 . 2 .
940955
941956** §4.1 .3 ** (_JVM , companion extensions_): companion extensions are compiled
942957as static members of the corresponding `FileKt ` class , without any value
@@ -946,7 +961,7 @@ are compiled into static private fields.
946961The name of this static member is the same given in the source code, unless
947962it has been overridden using a `@JvmName` annotation.
948963
949- ** ⌘ 4.1 .1 ** (_JVM example_): the code below,
964+ ** Example 4.1 .1 ** (_JVM example_): the code below,
950965
951966```kotlin
952967// in file 'Vector.kt'
@@ -967,7 +982,7 @@ is compiled into bytecode equivalent to the following Java code,
967982class Vector {
968983 // instance fields and constructor omitted
969984
970- private static Vector Zero ;
985+ private static final Vector Zero ;
971986 public static Vector getZero() { return Zero ; }
972987
973988 public static final int Dimensions = 2 ;
@@ -982,7 +997,7 @@ class VectorKt {
982997}
983998```
984999
985- ** ⌘ 4.1 .2 ** (_avoiding platform clashes_): the rules above may lead to platform
1000+ ** Example 4.1 .2 ** (_avoiding platform clashes_): the rules above may lead to platform
9861001clashes in both class bodies and companion extensions. Note that the JVM
9871002forbids defining a static and instance method with the same signature. The
9881003solution is to use `@JvmName` to rename one of them.
@@ -1053,6 +1068,11 @@ public class Vector {
10531068}
10541069```
10551070
1071+ ** §4.1 .5 ** (_JVM , expect/ actual matching_): the described compilation strategy
1072+ should be taken into account for `actual`izing an `expect` declaration with
1073+ a Java implementation. In particular, static members in a Java class may
1074+ `actual`ize companion block members.
1075+
10561076** §4.2 .1 ** (_JS , companion block members_): companion block members are
10571077compiled into [static members](https: // developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static)
10581078of the enclosing class .
@@ -1074,7 +1094,7 @@ into the initializer of that property.
10741094as any other top- level declaration. The name in JS is taken verbatim from
10751095the declaration, although it can be overridden using `@JsName`.
10761096
1077- ** ⌘ 4.2 .1 ** (_JS example_): the code below,
1097+ ** Example 4.2 .1 ** (_JS example_): the code below,
10781098
10791099```kotlin
10801100data class Vector (val x : Double , val y : Double ) {
@@ -1145,7 +1165,7 @@ as an [extension](https://docs.swift.org/swift-book/documentation/the-swift-prog
11451165holding the members. Other than that, the compilation scheme is similar
11461166to that of companion block members.
11471167
1148- ** ⌘ 4.3 .1 ** (_Swift example_): the code below,
1168+ ** Example 4.3 .1 ** (_Swift example_): the code below,
11491169
11501170```kotlin
11511171data class Vector (val x : Double , val y : Double ) {
@@ -1187,7 +1207,7 @@ the package is updated as follows.
11871207
118812082 . `KClass ` implements `KCompanionDeclarationContainer `.
11891209
1190- ** §6 .2** (_companion " receiver" _):
1210+ ** §5 .2** (_companion " receiver" _):
11911211the following property is added to `KCallable `. This property should be `null `
11921212whenever the callable is neither a companion extension nor defined in a
11931213companion block.
@@ -1215,7 +1235,7 @@ interface KCompanionParameter {
12151235Note that the `type` is a `KClass ` and not a `KType ` because those relate to
12161236the _class itself_, not a particular instantiation thereof.
12171237
1218- ** §6 .3** (_no additional arguments to `call`_):
1238+ ** §5 .3** (_no additional arguments to `call`_):
12191239no value should be passed in the position of receiver for neither
12201240companion block members nor companion extensions
12211241when using `call`, `callBy` from `KCallable `, and the corresponding
@@ -1239,7 +1259,7 @@ We should acknowledge that removing the companion object is
12391259a _binary breaking change_, and library authors should act accordingly.
12401260If their goal is to re- expose the same functionality from companion objects
12411261as companion blocks, the best solution is to use `@JvmStatic` (and similar
1242- annotations in other platforms). Another solution that improves on problem § 4
1262+ annotations in other platforms). Another solution that improves on problem # 4
12431263is to manually keep both versions, but that has additional boilerplate.
12441264
12451265```kotlin
@@ -1268,11 +1288,11 @@ platform. In this section we discuss how the entire proposal "translates" to
12681288the JVM side of things.
12691289
12701290Companion blocks translate to ** static members** . Since this mapping works well
1271- in both directions, this solves problems § 2 (mapping to platform statics) and
1272- § 5 (expect/ actual matching).
1291+ in both directions, this solves problems # 2 (mapping to platform statics) and
1292+ # 5 (expect/ actual matching).
12731293
12741294Using static members alleviate the need for an object allocation, solving
1275- problem § 4 . However , in order to have good performance, we need a way to
1295+ problem # 4 . However , in order to have good performance, we need a way to
12761296prevent re- computation of values; for that reason the proposal allows for
12771297properties in companion blocks and companion extensions to have ** backing
12781298fields and initializers** .
0 commit comments