File: name-resolution-motivation.md

package info (click to toggle)
kotlin 1.3.31%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 109,524 kB
  • sloc: java: 454,753; xml: 18,599; javascript: 10,452; sh: 513; python: 97; makefile: 54; ansic: 4
file content (58 lines) | stat: -rw-r--r-- 1,338 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
## Motivation

#### Locals have the highest priority

A variable of function type goes before members:
 
```
class A { fun foo() = 1 }

fun test(a: A, foo: () -> Int) {
    with (a) {
        foo()
    }
}
```

In anonymous objects local variables are chosen, not members:

```
interface A {
    val foo: Int
}

fun createA(foo: Int) = object : A {
    override val foo = foo
}
```

#### Top-level scope chain
 
The priorities: explicit imports; functions in the same package; star-imports; function from stdlib.

Explicit import should hide descriptors imported by `*`.

There is no scope for file, because moving a function to another file in the same package should not change the resolution.

The function imported explicitly goes before the function from the same package; the latter one may live in another file.

#### The order of implicit receivers

See the discussion here: https://youtrack.jetbrains.com/issue/KT-10510.

## Technical notes
 
When we resolve a property `foo` for a call `foo()` we don't stop on the first property, but instead we collect all variables with the name `foo` and for each of them try to find the `invoke` function:
 
``` 
class A {
    val foo: () -> Unit = { println("Hello world!") }
}

fun test(foo: Int) {
    with(A()) {
        foo   // parameter
        foo() // property + invoke
    }
}
```