private class ExtractAPICollector
extends 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 final 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

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 i...

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

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

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 annot...

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.