Skip to content

Commit 8c5d3b1

Browse files
committed
Draft for property overload resolution
1 parent f007f5b commit 8c5d3b1

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

docs/src/md/kotlin.core/overload-resolution.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,64 @@ TODO(Explain why anonymous function declarations DO NOT have a defined type w.r.
621621
> }
622622
> ```
623623
624+
### Resolving properties
625+
626+
As [properties][Property declaration] in Kotlin can have custom [getters and setters], be [extension][Extension property declaration], [delegated][Delegated property declaration] or [contextual][Contextual property declaration], they are also subject to overload resolution.
627+
Overload resolution for properties works similarly to how it works for [callables][Callables and `invoke` convention], i.e., it consists of two steps: [building the overload candidate set] of [applicable][Determining function applicability for a specific call] candidates, and then [choosing the most specific candidate from the overload candidate set].
628+
629+
Informally, access to a property is resolved as if it is a callable invocation corresponding to its getter or setter, and the overload resolution is performed on this invocation.
630+
631+
> Example: one may consider property access in class `A` to be resolved as if it has been transformed to class `AA`.
632+
>
633+
> ```kotlin
634+
> class A {
635+
> val a: Int = 5 // (1)
636+
>
637+
> val Double.a: Boolean // (2)
638+
> get() = this != 42.0
639+
>
640+
> fun test() {
641+
>
642+
> println(a) // Resolves to (1)
643+
>
644+
> with(42.0) {
645+
> println(this@A.a) // Resolves to (1)
646+
> println(this.a) // Resolves to (2)
647+
> println(a) // Resolves to (2)
648+
> }
649+
> }
650+
> }
651+
> ```
652+
>
653+
> ```kotlin
654+
> class AA {
655+
> fun a(): Int = 5 // (1)
656+
>
657+
> fun Double.a(): Boolean // (2)
658+
> = this != 42.0
659+
>
660+
> fun test() {
661+
>
662+
> println(a()) // Resolves to (1)
663+
>
664+
> with(42.0) {
665+
> println(this@AA.a()) // Resolves to (1)
666+
> println(this.a()) // Resolves to (2)
667+
> println(a()) // Resolves to (2)
668+
> }
669+
> }
670+
> }
671+
> ```
672+
673+
The overload resolution for properties has the following features distinct from overload resolution for callables.
674+
675+
* Properties without getter or setter are assumed to have default implementations for accessors;
676+
* The overload resolution takes into account the kind of property (e.g., an extension read-only property is considered to have an extension getter, a contextual mutable property is considered to have a contextual getter and setter, etc.);
677+
* When building the overload candidate set, only candidates which are property getters and setters are considered;
678+
> Note: this means `invoke` operator convention cannot take part in _property_ overload resolution.
679+
680+
TODO(Anything else?)
681+
624682
### Resolving callable references
625683
626684
[Callable references] introduce a special case of overload resolution which is somewhat similar to how regular calls are resolved, but different in several important aspects.

0 commit comments

Comments
 (0)