Dotty Documentation


class SuperAccessors
extends Object

This class performs the following functions:

(1) Adds super accessors for all super calls that either appear in a trait or have as a target a member of some outer class.

(2) Adds protected accessors if the access to the protected member happens in a class which is not a subclass of the member's owner.

It also checks that:

(1) Symbols accessed from super are not abstract, or are overridden by an abstract override.

(2) If a symbol accessed from super is defined in a real class (not a trait), there are no abstract members which override this member in Java's rules (see SI-4989; such an access would lead to illegal bytecode)

(3) Super calls do not go to some synthetic members of Any (see isDisallowed)

(4) Super calls do not go to synthetic field accessors

[-] Constructors

SuperAccessors ( thisPhase: DenotTransformer )

[-] Members

[+] private val accDefs : MutableSymbolMap [ ListBuffer [ Tree ] ]

List buffers for new accessor definitions, indexed by class

[+] private var invalidEnclClass : Symbol

Some parts of trees will get a new owner in subsequent phases. These are value class methods, which will become extension methods. (By-name arguments used to be included also, but these don't get a new class anymore, they are just wrapped in a new method).

These regions will have to be treated specially for the purpose of adding accessors. For instance, super calls from these regions always have to go through an accessor.

The invalidEnclClass field, if different from NoSymbol, contains the symbol that is not a valid owner.

[+] private val thisPhase : DenotTransformer
[+] private def ensureProtectedAccessOK ( sel: Select , targs: List [ Tree ] ) ( implicit ctx: Context ) : Tree

Replace sel (or sel[targs] if targs is nonempty) with a protected accessor call, if necessary.

[+] private def hostForAccessorOf ( sym: Symbol , referencingClass: ClassSymbol ) ( implicit ctx: Context ) : ClassSymbol

Return the innermost enclosing class C of referencingClass for which either of the following holds: - C is a subclass of sym.owner or - C is declared in the same package as sym's owner

[+] private def isDisallowed ( sym: Symbol ) ( implicit ctx: Context ) : Boolean

Disallow some super.XX calls targeting Any methods which would otherwise lead to either a compiler crash or runtime failure.

[+] def isProtectedAccessor ( tree: Tree ) ( implicit ctx: Context ) : Boolean
[+] private def isThisType ( tpe: Type ) ( implicit ctx: Context ) : Boolean

Is 'tpe' a ThisType, or a type proxy with a ThisType as transitively underlying type?

[+] private def needsProtectedAccessor ( sym: Symbol , pos: Position ) ( implicit ctx: Context ) : Boolean

Does sym need an accessor when accessed from currentClass? A special case arises for classes with explicit self-types. If the self type is a Java class, and a protected accessor is needed, we issue an error. If the self type is a Scala class, we don't add an accessor. An accessor is not needed if the access boundary is larger than the enclosing package, since that translates to 'public' on the host sys. (as Java has no real package nesting).

If the access happens inside a 'trait', access is more problematic since the implementation code is moved to an '$class' class which does not inherit anything. Since we can't (yet) add accessors for 'required' classes, this has to be signaled as error. FIXME Need to better understand this logic

[+] private def protectedAccessor ( tree: Select , targs: List [ Tree ] ) ( implicit ctx: Context ) : Tree
[+] private def protectedAccessorCall ( sel: Select , targs: List [ Tree ] ) ( implicit ctx: Context ) : Tree

Add a protected accessor, if needed, and return a tree that calls the accessor and returns the same member. The result is already typed.

[+] private def protectedSetter ( tree: Select ) ( implicit ctx: Context ) : Tree
[+] private def superAccessorCall ( sel: Select ) ( implicit ctx: Context ) : Select

A super accessor call corresponding to sel

[+] def transformAssign ( tree: Tree ) ( implicit ctx: Context ) : Tree

Transform assignment, adding a protected setter if needed

[+] def transformSelect ( tree: Tree , targs: List [ Tree ] ) ( implicit ctx: Context ) : Tree

Transform select node, adding super and protected accessors as needed

[+] private def transformSuperSelect ( sel: Select ) ( implicit ctx: Context ) : Tree

Check selection super.f for conforming to rules. If necessary, replace by a super accessor call.

[+] private def validCurrentClass ( implicit ctx: Context ) : Boolean
[+] private def withInvalidCurrentClass ( trans: => A ) ( implicit ctx: Context ) : A
[+] def wrapDefDef ( ddef: DefDef ) ( op: => DefDef ) ( implicit ctx: Context ) : DefDef

Wrap DefDef producing operation op, potentially setting invalidClass info

[+] def wrapTemplate ( tree: Template ) ( op: Template => Template ) ( implicit ctx: Context ) : Template

Wrap template to template transform op with needed initialization and finalization