Ward Bonnefond
08/21/2025, 5:08 PMdmitriy.novozhilov
08/22/2025, 6:59 AM// FILE: a.kt
fun foo() = bar().inc()
fun baz() {}
// FILE: b.kt
fun bar() = 1 + 1
Here we start analysis from file a.kt, but when we enter the body of fun foo we need to jump to file b.kt and analyse fun bar first, otherwise it would be impossible to resolve .inc() call on bar() receiver.
2. There are some computations not stored directly inside the tree (which represent the code), but in some additional services. These computations are usually lazy (computed only when there is an actual reason for that) and cached. The good example of such computation is deserialization of dependencies: when there is a reference to some class from dependencies (e.g. to ArrayList from stdlib) the compiler need to scan the classpath for that class, read its metadata from .class file and convert it to the object which is used by the compiler. This operation is quite heavy (e.g. it involves IO), so we want to do it only once and cache the result for further invocations.
This caching means, that the time spent on analysis of each file will depend on the order in which files were analyzed (and subtract the time of such computations from the total time of file analysis is quite problematic).