| ## 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 |
| } |
| } |
| ``` |