Index: docs/language/dartLangSpec.tex |
=================================================================== |
--- docs/language/dartLangSpec.tex (revision 38200) |
+++ docs/language/dartLangSpec.tex (working copy) |
@@ -3270,8 +3270,27 @@ |
\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 $o$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$. |
+Then the method \code{noSuchMethod()} is looked up in $o$ 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 $o$ 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'}. |
+\item \code{im.positionalArguments} evaluates to an immutable list whose sole element is $im$. |
+\item \code{im.namedArguments} evaluates to an empty immutable map. |
+\end{itemize} |
+and the result of the latter invocation is the result of evaluating $i$. |
+ |
+\rationale { |
+It is possible to bring about such a situation by overriding \code{noSuchMethod()} with the wrong number of arguments:} |
+ |
+\begin{code} |
+\CLASS{} Perverse \{ |
+ noSuchMethod(x,y) =$>$ x + y; |
+\} |
+ |
+\NEW{} Perverse.unknownMethod(); |
+\end{code} |
+ |
\commentary{Notice that the wording carefully avoids re-evaluating the receiver $o$ and the arguments $a_i$. } |
Let $T$ be the static type of $o$. It is a static type warning if $T$ does not have an accessible (\ref{privacy}) instance member named $m$ unless $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. If $T.m$ exists, it is a static type warning if the type $F$ of $T.m$ may not be assigned to a function type. If $T.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$. |
@@ -3367,8 +3386,17 @@ |
\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$. |
+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 : |
+\begin{itemize} |
+\item \code{im.isMethod} evaluates to \code{\TRUE{}}. |
+\item \code{im.memberName} evaluates to \code{noSuchMethod}. |
+\item \code{im.positionalArguments} evaluates to an immutable list whose sole element is $im$. |
+\item \code{im.namedArguments} evaluates to an empty immutable map. |
+\end{itemize} |
+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. |
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$. |
@@ -3417,8 +3445,16 @@ |
\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 $o$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$. |
+Then the method \code{noSuchMethod()} is looked up in $o$ 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 $o$ 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}. |
+\item \code{im.positionalArguments} evaluates to an immutable list whose sole element is $im$. |
+\item \code{im.namedArguments} evaluates to an empty immutable map. |
+\end{itemize} |
+and the result of this latter invocation is the result of evaluating $i$. |
+ |
Let $T$ be the static type of $e$. It is a static type warning if $T$ does not have a getter named $m$ unless $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. The static type of $i$ is the declared return type of $T.m$, if $T.m$ exists; otherwise the static type of $i$ is \DYNAMIC{}. |
Evaluation of a getter invocation $i$ of the form $C.m$ proceeds as follows: |
@@ -3448,10 +3484,16 @@ |
\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$. |
+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 : |
+\begin{itemize} |
+\item \code{im.isMethod} evaluates to \code{\TRUE{}}. |
+\item \code{im.memberName} evaluates to \code{noSuchMethod}. |
+\item \code{im.positionalArguments} evaluates to an immutable list whose sole element is $im$. |
+\item \code{im.namedArguments} evaluates to an empty immutable map. |
+\end{itemize} |
+and the result of this latter invocation is the result of evaluating $i$. |
- |
It is a static type warning if $S$ does not have a getter named $m$. The static type of $i$ is the declared return type of $S.m$, if $S.m$ exists; otherwise the static type of $i$ is \DYNAMIC{}. |
Evaluation of a getter invocation of the form $p.C.v$, where $p$ is a deferred prefix, proceeds as follows: |
@@ -3534,8 +3576,17 @@ |
\item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
\end{itemize} |
-Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked with argument $im$. The value of the assignment expression is $o_2$ irrespective of whether setter lookup has failed or succeeded. |
+Then the method \code{noSuchMethod()} is looked up in $o_1$ 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 $o_1$ 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}. |
+\item \code{im.positionalArguments} evaluates to an immutable list whose sole element is $im$. |
+\item \code{im.namedArguments} evaluates to an empty immutable map. |
+\end{itemize} |
+The value of the assignment expression is $o_2$ irrespective of whether setter lookup has failed or succeeded. |
+ |
Evaluation of an assignment of the form $p.v \code{=} e$, where $p$ is a deferred prefix, proceeds as follows: |
If $p$ has been successfully loaded, the assignment is evaluated exactly like the assignment $w \code{=} e$, where $w$ denotes the top level member named $v$ of the library represented by $p$. Otherwise, $e$ is evaluated and then a \code{NoSuchMethodError} is thrown. |