Dotty Documentation

0.4.0-bin-SNAPSHOT

private class ExtractAPICollector
extends Object with ThunkHolder

Extracts full (including private members) API representation out of Symbols and Types.

The exact representation used for each type is not important: the only thing that matters is that a binary-incompatible or source-incompatible change to the API (for example, changing the signature of a method, or adding a parent to a class) should result in a change to the API representation so that sbt can recompile files that depend on this API.

Note that we only records types as they are defined and never "as seen from" some other prefix because Types#asSeenFrom is a complex operation and doing it for every inherited member would be slow, and because the number of prefixes can be enormous in some cases:

class Outer { type T <: S type S class A extends Outer { /.../ } class B extends Outer { /.../ } class C extends Outer { /.../ } class D extends Outer { /.../ } class E extends Outer { /.../ } }

S might be refined in an arbitrary way inside A for example, this affects the type of T as seen from Outer#A, so we could record that, but the class A also contains itself as a member, so Outer#A#A#A#... is a valid prefix for T. Even if we avoid loops, we still have a combinatorial explosion of possible prefixes, like Outer#A#B#C#D#E.

It is much simpler to record T once where it is defined, but that means that the API representation of T may not change even though T as seen from some prefix has changed. This is why in ExtractDependencies we need to traverse used types to not miss dependencies, see the documentation of ExtractDependencies#usedTypeTraverser.

TODO: sbt does not store the full representation that we compute, instead it hashes parts of it to reduce memory usage, then to see if something changed, it compares the hashes instead of comparing the representations. We should investigate whether we can just directly compute hashes in this phase without going through an intermediate representation, see http://www.scala-sbt.org/0.13/docs/Understanding-Recompilation.html#Hashing+an+API+representation

[-] Constructors

ExtractAPICollector ( )
ExtractAPICollector ( implicit ctx: Context )

[-] Members

[+] private object Constants
[+] private val LegacyAppClass : ClassSymbol
[+] val byNameMarker : Annotation
[+] private val classLikeCache : HashMap [ ClassSymbol, ClassLike ]

This cache is necessary for correctness, see the comment about inherited members in apiClassStructure

[+] implicit val ctx : Context
[+] val orMarker : Annotation
[+] private val refinedTypeCache : HashMap [ ( Type, Definition ), Structure ]

This cache is necessary to avoid unstable name hashing when typeCache is present, see the comment in the RefinedType case in computeType The cache key is (api of RefinedType#parent, api of RefinedType#refinedInfo).

[+] private val typeCache : HashMap [ Type, Type ]

This cache is optional, it avoids recomputing representations

[+] def apiAccess ( sym: Symbol ) : Access
[+] def apiAnnotation ( annot: Annotation ) : Annotation
[+] def apiAnnotations ( s: Symbol ) : List [ Annotation ]
[+] def apiClass ( sym: ClassSymbol ) : ClassLike
[+] def apiClassStructure ( csym: ClassSymbol ) : Structure
[+] def apiDef ( sym: TermSymbol ) : Def
[+] def apiDefinition ( sym: Symbol ) : Definition
[+] def apiDefinitions ( defs: List [ Symbol ] ) : List [ Definition ]
[+] def apiLazy ( tp: => Type ) : Type
[+] def apiModifiers ( sym: Symbol ) : Modifiers
[+] def apiSource ( tree: Tree ) : SourceAPI

Extract the API representation of a source file

[+] def apiThis ( sym: Symbol ) : Singleton
[+] def apiType ( tp: Type ) : Type
[+] def apiTypeMember ( sym: TypeSymbol ) : TypeMember
[+] def apiTypeParameter ( tparam: ParamInfo ) : TypeParameter
[+] def apiTypeParameter ( name: String , variance: Int , lo: Type , hi: Type ) : TypeParameter
[+] def apiVariance ( v: Int ) : Variance
[+] private def computeClass ( sym: ClassSymbol ) : ClassLike
[+] private def computeType ( tp: Type ) : Type
[+] def linearizedAncestorTypes ( info: ClassInfo ) : List [ Type ]
[+] private def marker ( name: String ) : Annotation
[+] def simpleType ( tp: Type ) : SimpleType
[+] private def withMarker ( tp: Type , marker: Annotation ) : Annotated

Some Dotty types do not have a corresponding type in xsbti.api.* that represents them. Until this is fixed we can workaround this by using special annotations that can never appear in the source code to represent these types.