Dotty Documentation


class ExtractDependenciesCollector
extends TreeTraverser

Extract the dependency information of a compilation unit.

To understand why we track the used names see the section "Name hashing algorithm" in To understand why we need to track dependencies introduced by inheritance specially, see the subsection "Dependencies introduced by member reference and inheritance" in the "Name hashing algorithm" section.

[-] Constructors

ExtractDependenciesCollector ( )

[-] Members

[+] private abstract class TypeDependencyTraverser

Traverse a used type and record all the dependencies we need to keep track of for incremental recompilation.

As a motivating example, given a type T defined as:

type T >: L <: H type L <: A1 type H <: B1 class A1 extends A0 class B1 extends B0

We need to record a dependency on T, L, H, A1, B1. This is necessary because the API representation that ExtractAPI produces for T just refers to the strings "L" and "H", it does not contain their API representation. Therefore, the name hash of T does not change if for example the definition of L changes.

We do not need to keep track of superclasses like A0 and B0 because the API representation of a class (and therefore its name hash) already contains all necessary information on superclasses.

A natural question to ask is: Since traversing all referenced types to find all these names is costly, why not change the API representation produced by ExtractAPI to contain that information? This way the name hash of T would change if any of the types it depends on change, and we would only need to record a dependency on T. Unfortunately there is no simple answer to the question "what does T depend on?" because it depends on the prefix and ExtractAPI does not compute types as seen from every possible prefix, the documentation of ExtractAPI explains why.

The tests in sbt types-in-used-names-a, types-in-used-names-b, as-seen-from-a and as-seen-from-b rely on this.

[+] private val _dependencies : HashSet [ ClassDependency ]
[+] private var _responsibleForImports : Symbol

Top level import dependencies are registered as coming from a first top level class/trait/object declared in the compilation unit. If none exists, issue warning.

[+] private val _usedNames : HashMap [ Symbol, UsedNamesInClass ]
[+] private var lastDepSource : Symbol
[+] private var lastOwner : Symbol
[+] private def addInheritanceDependencies ( tree: Template ) ( implicit ctx: Context ) : Unit
[+] private def addMemberRefDependency ( sym: Symbol ) ( implicit ctx: Context ) : Unit
[+] def addPatMatDependency ( tpe: Type ) ( implicit ctx: Context ) : Unit
[+] def addTypeDependency ( tpe: Type ) ( implicit ctx: Context ) : Unit
[+] private def addUsedName ( fromClass: Symbol , name: Name , scope: UseScope ) : Unit
[+] private def addUsedName ( name: Name , scope: UseScope ) ( implicit ctx: Context ) : Unit
[+] def dependencies : Set [ ClassDependency ]

The set of class dependencies from this compilation unit.

[+] private def ignoreDependency ( sym: Symbol ) ( implicit ctx: Context ) : Boolean
[+] private def mangledName ( sym: Symbol ) ( implicit ctx: Context ) : Name

Mangle a JVM symbol name in a format better suited for internal uses by sbt.

[+] private def resolveDependencySource ( implicit ctx: Context ) : Symbol

Resolves dependency source (that is, the closest non-local enclosing class from a given ctx.owner

[+] private def responsibleForImports ( implicit ctx: Context ) : Symbol
[+] override def traverse ( tree: Tree ) ( implicit ctx: Context ) : Unit

Traverse the tree of a source file and record the dependencies and used names which can be retrieved using dependencies andusedNames.

[+] def usedNames : Map [ Symbol, UsedNamesInClass ]

The names used in this class, this does not include names which are only defined and not referenced.