The language specification specifies that top level scopes are populated with entities in the following manner (Sect. Imports):
The {\em public namespace} of library $L$ is the mapping that maps the simple name
of each public top-level member $m$ of $L$ to $m$.
The scope of a library $L$ consists of the names introduced by all top-level declarations
declared in $L$, and the names added by $L$'s imports (\ref{imports}).
This means that the top level scope of $L$ will bind the name of each class declared in $L$ to that class. So we can look up a class as such in the current library. This is confirmed by the following (Sect. Mixin Application):
The effect of a class definition of the form \code{\CLASS{} $C$ = $M$; } or the form
\code{\CLASS{} $C<T_1, \ldots, T_n>$ = $M$; } in library $L$ is to introduce the name
$C$ into the scope of $L$, bound to the class (\ref{classes}) defined by the mixin
application $M$.
I couldn't find a similar statement about regular class declarations, but you could claim that both mixin applications and regular class definitions are covered by the general rule about library scopes above.
The library namespace is used to define how imports work, and this means that we can look up classes as such from libraries that are imported 'immediately' (without a prefix).
However, when we import with a prefix we obtain a getter which returns the Type
(Sect. Imports, talking about the members of prefix objects):
For every type $T$ named $id$ in $NS_n$, a corresponding getter named $id$ with return
type \code{Type}, that, when invoked, returns the type object for $T$.
So we sometimes have the getter which is used dynamically for obtaining a Type
, and in that situation we don't have a suitable notion of what's in scope for the static analysis (where we'd want to look up the class as such), and we sometimes have the classes as such, and then we don't have a suitable getter which is needed at runtime (foo() => C;
).
We can't just add both entries and use the resulting scopes both for static analysis and at runtime, because that would cause a name clash for every type name.
So we probably need to distinguish between static and dynamic scopes.
Members are defined in bits and pieces:
% Sect. Libraries and Scripts
The members of a library $L$ are those top level declarations given within $L$.
% Sect. Classes
The instance members of a class are its instance methods, getters, setters and
instance variables. The static members of a class are its static methods, getters,
setters and static variables. The members of a class are its static and instance members.
So in both cases members are declarations, including variables.
But we also have this:
% Sect. Variables
A library variable introduces a getter into the top level scope of the enclosing library.
A static class variable introduces a static getter into the immediately enclosing class.
An instance variable introduces an instance getter into the immediately enclosing class.
A mutable library variable introduces a setter into the top level scope of the enclosing library.
A mutable static class variable introduces a static setter into the immediately enclosing class.
A mutable instance variable introduces an instance setter into the immediately enclosing class.
So a library scope may contain both a variable x
and a getter x
induced by the variable, which creates a name clash for every single variable.
For that, I guess we can just insist that variables are not added to any scopes, only the induced setters and getters are. This should work dynamically as well as for the static analysis.
Finally, I can't find any indication that type parameters are added to any scopes. We do get a specification that there is a scope for them (Sect. Classes):
A class has several scopes:
\begin{itemize}
\item A {\em type-parameter scope}, which is empty if the class is not generic
(\ref{generics}). The enclosing scope of the type-parameter scope of a class is
the enclosing scope of the class declaration.
\item A {\em static scope}. The enclosing scope of the static scope of a class is
the type parameter scope (\ref{generics}) of the class.
\item An {\em instance scope}. The enclosing scope of a class' instance scope is
the class' static scope.
\end{itemize}
This means that the usual problem with other scopes is avoided: Since we don't add type parameters to any scopes we don't have a name clash between the type parameter as such and a getter with return type Type
. But if we fill in that missing information we'd need a similar solution. ;-)