Index: docs/language/dartLangSpec.tex |
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex |
index 110d88f497e16e3c462682b59bda4c4fd10cc294..94f1135dba3cde3bcdf1bcd82aacbdd2321ee829 100644 |
--- a/docs/language/dartLangSpec.tex |
+++ b/docs/language/dartLangSpec.tex |
@@ -6,7 +6,7 @@ |
\usepackage{hyperref} |
\usepackage{lmodern} |
\newcommand{\code}[1]{{\sf #1}} |
-\title{Dart Programming Language Specification \\ |
+\title{Dart Programming Language Specification (Mixin DEP)\\ |
{\large Version 1.10}} |
% For information about Location Markers (and in particular the |
@@ -2012,18 +2012,12 @@ The current solution is a tad complex, but is robust in the face of type annotat |
A mixin describes the difference between a class and its superclass. A mixin is always derived from an existing class declaration. |
\LMHash{} |
-It is a compile-time error if a declared or derived mixin refers to \SUPER{}. It is a compile-time error if a declared or derived mixin explicitly declares a constructor. It is a compile-time error if a mixin is derived from a class whose superclass is not \code{Object}. |
+It is a compile-time error if a declared or derived mixin explicitly declares a constructor. |
\rationale{ |
These restrictions are temporary. We expect to remove them in later versions of Dart. |
-The restriction on the use of \SUPER{} avoids the problem of rebinding \SUPER{} when the mixin is bound to difference superclasses. |
- |
The restriction on constructors simplifies the construction of mixin applications because the process of creating instances is simpler. |
- |
-The restriction on the superclass means that the type of a class from which a mixin is derived is always implemented by any class that mixes it in. This allows us to defer the question of whether and how to express the type of the mixin independently of its superclass and super interface types. |
- |
-Reasonable answers exist for all these issues, but their implementation is non-trivial. |
} |
\subsection{Mixin Application} |
@@ -2077,6 +2071,12 @@ If, for example, $M$ declares an instance member $im$ whose type is at odds with |
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$. The name of the class is also set to $C$. Iff the class is prefixed by the built-in identifier \ABSTRACT{}, the class being defined is an abstract class. |
+ Let $M_A$ be a mixin derived from a class $M$ with direct superclass $S$. |
+ |
+Let $A$ be an application of $M_A$. It is a static warning if the superclass of $A$ is not a subtype of $S$. |
eernst
2015/06/23 15:45:03
Maybe these two occurrences of $S$ should be chang
gbracha
2015/06/23 19:53:47
It doesn't matter much as there is no question of
|
+ |
+Let $C$ be a class declaration that includes $M_A$ in a with clause. It is a static warning if $C$ does not implement, directly or indirectly, all the direct superinterfaces of $M$. |
Lasse Reichstein Nielsen
2015/06/23 08:06:23
Does this need a `@proxy` exception too? That is,
gbracha
2015/06/23 19:53:47
Short answer: No.
Long answer:
For whatever dark
|
+ |
\subsection{Mixin Composition} |
\LMLabel{mixinComposition} |
@@ -3733,7 +3733,7 @@ The result of a lookup of a method $m$ in object $o$ with respect to library $L$ |
\LMHash{} |
The result of a lookup of method $m$ in class $C$ with respect to library $L$ is: |
-If $C$ declares a concrete instance method named $m$ that is accessible to $L$, then that method is the result of the lookup. Otherwise, if $C$ has a superclass $S$, then the result of the lookup is the result of looking up $m$ in $S$ with respect to $L$. Otherwise, we say that the method lookup has failed. |
+If $C$ declares a concrete instance method named $m$ that is accessible to $L$, then that method is the result of the lookup, and we say that the method was {\em looked up in $C$}. Otherwise, if $C$ has a superclass $S$, then the result of the lookup is the result of looking up $m$ in $S$ with respect to $L$. Otherwise, we say that the method lookup has failed. |
eernst
2015/06/23 15:45:03
Would it be better to find all occurrences of 'sup
gbracha
2015/06/23 19:53:48
Lasse made a similar comment for one specific case
|
\rationale { |
The motivation for skipping abstract members during lookup is largely to allow smoother mixin composition. |
@@ -3748,7 +3748,7 @@ The result of a lookup of a getter (respectively setter) $m$ in object $o$ with |
\LMHash{} |
The result of a lookup of a getter (respectively setter) $m$ in class $C$ with respect to library $L$ is: |
-If $C$ declares a concrete instance getter (respectively setter) named $m$ that is accessible to $L$, then that getter (respectively setter) is the result of the lookup. Otherwise, if $C$ has a superclass $S$, then the result of the lookup is the result of looking up getter (respectively setter) $m$ in $S$ with respect to $L$. Otherwise, we say that the lookup has failed. |
+If $C$ declares a concrete instance getter (respectively setter) named $m$ that is accessible to $L$, then that getter (respectively setter) is the result of the lookup, and we say that the getter (respectively setter) was {\em looked up in $C$}. Otherwise, if $C$ has a superclass $S$, then the result of the lookup is the result of looking up getter (respectively setter) $m$ in $S$ with respect to $L$. Otherwise, we say that the lookup has failed. |
\rationale { |
The motivation for skipping abstract members during lookup is largely to allow smoother mixin composition. |
@@ -3919,7 +3919,7 @@ $\SUPER{}.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
Evaluation of $i$ proceeds as follows: |
\LMHash{} |
-First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated yielding actual argument objects $o_1, \ldots , o_{n+k}$. Let $S$ be the superclass of the immediately enclosing class, and let $f$ be the result of looking up method (\ref{methodLookup}) $m$ in $S$ with respect to the current library $L$. |
+First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated yielding actual argument objects $o_1, \ldots , o_{n+k}$. Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up (\ref{methodLookup}). Let $S_{dynamic}$ be the superclass of $C$, and let $f$ be the result of looking up method (\ref{methodLookup}) $m$ in $S_{dynamic}$ with respect to the current library $L$. |
Lasse Reichstein Nielsen
2015/06/19 09:36:27
This requires the lookup-class of a method to be r
eernst
2015/06/23 15:45:03
$S_{dynamic}$ seems to imply that the given class
eernst
2015/06/23 15:45:03
Actually, the method would be 'looked up in' the c
gbracha
2015/06/23 19:53:48
It's easy if the implementation copies down method
gbracha
2015/06/23 19:53:48
It's constant until you have dynamic mixin applica
Lasse Reichstein Nielsen
2015/06/24 12:16:10
The result of doing super.foo in the X.superFoo ge
|
Let $p_1 \ldots p_h$ be the required parameters of $f$, let $p_1 \ldots p_m$ be the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+l}$ be the optional parameters declared by $f$. |
Lasse Reichstein Nielsen
2015/06/19 09:36:27
This seems to assume that $f$ is found.
How about:
gbracha
2015/06/23 19:53:48
Yes, this assumes that other lookup failures are h
|
\LMHash{} |
@@ -3929,8 +3929,8 @@ If $n < h$, or $n > m$, the method lookup has failed. Furthermore, each $x_i, n |
If the method lookup succeeded, the body of $f$ is executed with respect to the bindings that resulted from the evaluation of the argument list, and with \THIS{} bound to the current value of \THIS{}. The value of $i$ is the value returned after $f$ is executed. |
\LMHash{} |
-If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $S$ with respect to $L$. If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $\SUPER{}.m$. Then the value of $i$ is the result of invoking |
-the static method \code{Function.apply()} with arguments $v.g, [o_1, \ldots , o_n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$. |
+If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $S_{dynamic}$ with respect to $L$. If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $\SUPER{}.m$. Then the value of $i$ is the result of invoking |
+the static method \code{Function.apply()} with arguments $v_g, [o_1, \ldots , o_n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$. |
\LMHash{} |
If getter lookup has also failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that : |
@@ -3940,7 +3940,7 @@ If getter lookup has also failed, then a new instance $im$ of the predefined c |
\item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_1, \ldots, o_n$]}. |
\item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}. |
\end{itemize} |
-Then the method \code{noSuchMethod()} is looked up in $S$ and invoked on \THIS{} with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that : |
+Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked on \THIS{} with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that : |
\begin{itemize} |
\item \code{im'.isMethod} evaluates to \code{\TRUE{}}. |
\item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. |
@@ -3955,7 +3955,7 @@ and the result of this latter invocation is the result of evaluating $i$. |
It is a compile-time error if a super method invocation occurs in a top-level function or variable initializer, in an instance variable initializer or initializer list, in class \code{Object}, in a factory constructor or in a static method or variable initializer. |
\LMHash{} |
-It is a static type warning if $S$ does not have an accessible (\ref{privacy}) instance member named $m$ unless $S$ or a superinterface of $S$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. If $S.m$ exists, it is a static type warning if the type $F$ of $S.m$ may not be assigned to a function type. If $S.m$ does not exist, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declared return type of $F$. |
+Let $S_{static}$ be the superclass of the immediately enclosing class. It is a static type warning if $S_{static}$ does not have an accessible (\ref{privacy}) instance member named $m$ unless $S_{static}$ or a superinterface of $S_{static}$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. If $S_{static}.m$ exists, it is a static type warning if the type $F$ of $S_{static}.m$ may not be assigned to a function type. If $S_{static}.m$ does not exist, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declared return type of $F$. |
eernst
2015/06/23 15:45:03
Looking at this again, it does make a lot of sense
gbracha
2015/06/23 19:53:47
Not sure if you're agreeing with me or not. I'll a
|
% The following is not needed because it is specified in 'Binding Actuals to Formals" |
%Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static warning if $F$ is not a supertype of $(T_1, \ldots, t_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \to \bot$. |
@@ -4070,10 +4070,10 @@ The static type of $i$ is: |
Evaluation of a property extraction $i$ of the form $\SUPER.m$ proceeds as follows: |
\LMHash{} |
- Let $S$ be the superclass of the immediately enclosing class. Let $f$ be the result of looking up method $m$ in $S$ with respect to the current library $L$. If method lookup succeeds then $i$ evaluates to the closurization of method $f$ with respect to superclass $S$ (\ref{superClosurization}). |
+Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. Let $f$ be the result of looking up method $m$ in $S_{dynamic}$ with respect to the current library $L$. If method lookup succeeds then $i$ evaluates to the closurization of method $f$ with respect to superclass $S_{dynamic}$ (\ref{superClosurization}). |
\LMHash{} |
- Otherwise, $i$ is a getter invocation. Let $f$ be the result of looking up getter $m$ in $S$ with respect to $L$. The body of $f$ is executed with \THIS{} bound to the current value of \THIS{}. The value of $i$ is the result returned by the call to the getter function. |
+ Otherwise, $i$ is a getter invocation. Let $f$ be the result of looking up getter $m$ in $S_{dynamic}$ with respect to $L$. The body of $f$ is executed with \THIS{} bound to the current value of \THIS{}. The value of $i$ is the result returned by the call to the getter function. |
\LMHash{} |
If the getter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that : |
@@ -4083,7 +4083,7 @@ If the getter lookup has failed, then a new instance $im$ of the predefined cla |
\item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []}. |
\item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
\end{itemize} |
-Then the method \code{noSuchMethod()} is looked up in $S$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that : |
+Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that : |
\begin{itemize} |
\item \code{im'.isMethod} evaluates to \code{\TRUE{}}. |
\item \code{im'.memberName} evaluates to \code{\#noSuchMethod}. |
@@ -4093,12 +4093,12 @@ Then the method \code{noSuchMethod()} is looked up in $S$ and invoked with argu |
and the result of this latter invocation is the result of evaluating $i$. |
\LMHash{} |
-It is a static type warning if $S$ does not have an accessible instance method or getter named $m$. |
+Let $S_{static}$ be the superclass of the immediately enclosing class. It is a static type warning if $S_{static}$ does not have an accessible instance method or getter named $m$. |
Lasse Reichstein Nielsen
2015/06/19 09:36:27
Will this method be concrete, or can an abstract m
gbracha
2015/06/23 19:53:47
(1) This has nothing to do with this CL; it has to
|
The static type of $i$ is: |
\begin{itemize} |
-\item The declared return type of $S.m$, if $S$ has an accessible instance getter named $m$. |
-\item The static type of function $S.m$ if $S$ has an accessible instance method named $m$. |
+\item The declared return type of $S_{static}.m$, if $S_{static}$ has an accessible instance getter named $m$. |
+\item The static type of function $S_{static}.m$ if $S_{static}$ has an accessible instance method named $m$. |
\item The type \DYNAMIC{} otherwise. |
\end{itemize} |
@@ -4207,21 +4207,21 @@ The static type of $i$ is the type of the constructor function $T()$, if $T$ den |
Evaluation of a property extraction $i$ of the form \SUPER$\#m$ proceeds as follows: |
\LMHash{} |
-Let $S$ be the superclass of the immediately enclosing class. |
+Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. Let $S_{dynamic}$ be the superclass of the $C$. |
eernst
2015/06/23 15:45:03
Last sentence duplicated.
gbracha
2015/06/23 19:53:47
It's idempotent :-). Fixed.
|
\LMHash{} |
-If $m$ is a setter name, let $f$ be the result of looking up setter $m$ in $S$ with respect to the current library $L$. If setter lookup succeeds then $i$ evaluates to the closurization of setter $f$ with respect to superclass $S$ (\ref{superClosurization}). If setter lookup failed, a \cd{NoSuchMethodError} is thrown. |
+If $m$ is a setter name, let $f$ be the result of looking up setter $m$ in $S_{dynamic}$ with respect to the current library $L$. If setter lookup succeeds then $i$ evaluates to the closurization of setter $f$ with respect to superclass $S_{dynamic}$ (\ref{superClosurization}). If setter lookup failed, a \cd{NoSuchMethodError} is thrown. |
-If $m$ is not a setter name, let $f$ be the result of looking up method $m$ in $S$ with respect to the current library $L$. If method lookup succeeds then $i$ evaluates to the closurization of method $m$ with respect to superclass $S$ (\ref{superClosurization}). |
+If $m$ is not a setter name, let $f$ be the result of looking up method $m$ in $S_{dynamic}$ with respect to the current library $L$. If method lookup succeeds then $i$ evaluates to the closurization of method $m$ with respect to superclass $S_{dynamic}$ (\ref{superClosurization}). |
\LMHash{} |
- Otherwise, let $f$ be the result of looking up getter $m$ in $S$ with respect to the current library $L$. If getter lookup succeeds then $i$ evaluates to the closurization of getter $f$ with respect to superclass $S$ (\ref{superClosurization}). If getter lookup failed, a \cd{NoSuchMethodError} is thrown. |
+ Otherwise, let $f$ be the result of looking up getter $m$ in $S_{dynamic}$ with respect to the current library $L$. If getter lookup succeeds then $i$ evaluates to the closurization of getter $f$ with respect to superclass $S_{dynamic}$ (\ref{superClosurization}). If getter lookup failed, a \cd{NoSuchMethodError} is thrown. |
\LMHash{} |
-It is a static type warning if $S$ does not have an accessible instance member named $m$. |
+Let $S_{static}$ be the superclass of the immediately enclosing class.It is a static type warning if $S_{static}$ does not have an accessible instance member named $m$. |
\LMHash{} |
-The static type of $i$ is the static type of the function $S.m$, if $S$ has an accessible instance member named $m$. Otherwise the static type of $i$ is \DYNAMIC{}. |
+The static type of $i$ is the static type of the function $S_{static}.m$, if $S_{static}$ has an accessible instance member named $m$. Otherwise the static type of $i$ is \DYNAMIC{}. |
@@ -4483,8 +4483,8 @@ It is a static type warning if the static type of $e_2$ may not be assigned to t |
Evaluation of an assignment of the form $\SUPER.v$ \code{=} $e$ proceeds as follows: |
\LMHash{} |
-Let $S$ be the superclass of the immediately enclosing class. |
-The expression $e$ is evaluated to an object $o$. Then, the setter $v=$ is looked up (\ref{getterAndSetterLookup}) in $S$ with respect to the current library. The body of $v=$ is executed with its formal parameter bound to $o$ and \THIS{} bound to \THIS{}. |
+Let $g$ be the method currently executing, and let $C$ be the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. |
+The expression $e$ is evaluated to an object $o$. Then, the setter $v=$ is looked up (\ref{getterAndSetterLookup}) in $S_{dynamic}$ with respect to the current library. The body of $v=$ is executed with its formal parameter bound to $o$ and \THIS{} bound to \THIS{}. |
\LMHash{} |
If the setter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that : |
@@ -4496,7 +4496,7 @@ If the setter lookup has failed, then a new instance $im$ of the predefined cla |
\end{itemize} |
\LMHash{} |
-Then the method \code{noSuchMethod()} is looked up in $S$ and invoked with argument $im$. |
+Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$. |
However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that : |
\begin{itemize} |
\item \code{im'.isMethod} evaluates to \code{\TRUE{}}. |
@@ -4512,7 +4512,7 @@ The value of the assignment expression is $o$ irrespective of whether setter loo |
In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interface of the class of $o$ is not a subtype of the actual type of $S.v$. |
\LMHash{} |
-It is a static type warning if $S$ does not have an accessible instance setter named $v=$ unless $S$ or a superinterface of $S$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. |
+Let $S_{static}$ be the superclass of the immediately enclosing class. It is a static type warning if $S_{static}$ does not have an accessible instance setter named $v=$ unless $S_{static}$ or a superinterface of $S_{static}$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. |
\LMHash{} |
It is a static type warning if the static type of $e$ may not be assigned to the static type of the formal parameter of the setter $v=$. The static type of the expression $\SUPER.v$ \code{=} $e$ is the static type of $e$. |