OLD | NEW |
---|---|
1 \documentclass{article} | 1 \documentclass{article} |
2 \usepackage{epsfig} | 2 \usepackage{epsfig} |
3 \usepackage{color} | 3 \usepackage{color} |
4 \usepackage{dart} | 4 \usepackage{dart} |
5 \usepackage{bnf} | 5 \usepackage{bnf} |
6 \usepackage{hyperref} | 6 \usepackage{hyperref} |
7 \usepackage{lmodern} | 7 \usepackage{lmodern} |
8 \newcommand{\code}[1]{{\sf #1}} | 8 \newcommand{\code}[1]{{\sf #1}} |
9 \title{Dart Programming Language Specification \\ | 9 \title{Dart Programming Language Specification \\ |
10 {4th edition draft}\\ | 10 {4th edition draft}\\ |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 a program that interfaces between the engine and the surrounding computing envir onment. The embedder will often be a web browser, but need not be; it may be a C ++ program on the server for example. When an isolate fails with a compile-time error as described above, control returns to the embedder, along with an excepti on describing the problem. This is necessary so that the embedder can clean up resources etc. It is then the embedder's decision whether to terminate the isola te or not. | 317 a program that interfaces between the engine and the surrounding computing envir onment. The embedder will often be a web browser, but need not be; it may be a C ++ program on the server for example. When an isolate fails with a compile-time error as described above, control returns to the embedder, along with an excepti on describing the problem. This is necessary so that the embedder can clean up resources etc. It is then the embedder's decision whether to terminate the isola te or not. |
318 } | 318 } |
319 | 319 |
320 \LMHash{} | 320 \LMHash{} |
321 {\em Static warnings} are those errors reported by the static checker. They hav e no effect on execution. Many, but not all, static warnings relate to types, in which case they are known as {\em static type warnings.} Static warnings must b e provided by Dart compilers used during development such as those incorporated in IDEs or otherwise intended to be used by developers for developing code. Comp ilers that are part of runtime execution environments such as virtual machines s hould not issue static warnings. | 321 {\em Static warnings} are those errors reported by the static checker. They hav e no effect on execution. Many, but not all, static warnings relate to types, in which case they are known as {\em static type warnings.} Static warnings must b e provided by Dart compilers used during development such as those incorporated in IDEs or otherwise intended to be used by developers for developing code. Comp ilers that are part of runtime execution environments such as virtual machines s hould not issue static warnings. |
322 | 322 |
323 \LMHash{} | 323 \LMHash{} |
324 {\em Dynamic type errors} are type errors reported in checked mode. | 324 {\em Dynamic type errors} are type errors reported in checked mode. |
325 | 325 |
326 \LMHash{} | 326 \LMHash{} |
327 {\em Run-time errors} are exceptions raised during execution. Whenever we say th at an exception $ex$ is {\em raised} or {\em thrown}, we mean that a throw expre ssion (\ref{throw}) of the form: \code{\THROW{} $ex$;} was implicitly evaluated or that a rethrow statement (\ref{rethrow}) of the form \code{\RETHROW} was exe cuted. When we say that {\em a} $C$ {\em is thrown}, where $C$ is a class, we me an that an instance of class $C$ is thrown. When we say that a stream raises an exception, we mean that an exception occurred while computing the value(s) of th e stream. | 327 {\em Run-time errors} are exceptions raised during execution. Whenever we say th at an exception $ex$ is {\em raised} or {\em thrown}, we mean that a throw expre ssion (\ref{throw}) of the form: \code{\THROW{} $ex$;} was implicitly evaluated or that a rethrow statement (\ref{rethrow}) of the form \code{\RETHROW} was exe cuted. When we say that {\em a} $C$ {\em is thrown}, where $C$ is a class, we me an that an instance of class $C$ is thrown. When we say that a stream raises an exception, we mean that the stream emits the exception and its associated stack trace as an error event. |
Kevin Millikin (Google)
2016/10/13 12:18:37
I'd be quite happy if we only every said "raised"
Lasse Reichstein Nielsen
2016/10/17 10:08:22
I thought about removing the `rethrow` part, but a
| |
328 | 328 |
329 \LMHash{} | 329 \LMHash{} |
330 If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately suspended. | 330 If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately suspended. |
331 | 331 |
332 | 332 |
333 \section{Variables} | 333 \section{Variables} |
334 \LMLabel{variables} | 334 \LMLabel{variables} |
335 | 335 |
336 \LMHash{} | 336 \LMHash{} |
337 Variables are storage locations in memory. | 337 Variables are storage locations in memory. |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1207 | 1207 |
1208 % The enclosing scope of a generative constructor is the instance scope of the c lass in which it is declared (but what about redirecting?) | 1208 % The enclosing scope of a generative constructor is the instance scope of the c lass in which it is declared (but what about redirecting?) |
1209 | 1209 |
1210 \LMHash{} | 1210 \LMHash{} |
1211 Iff no constructor is specified for a class $C$, it implicitly has a default con structor \code{C() : \SUPER{}() \{\}}, unless $C$ is class \code{Object}. | 1211 Iff no constructor is specified for a class $C$, it implicitly has a default con structor \code{C() : \SUPER{}() \{\}}, unless $C$ is class \code{Object}. |
1212 | 1212 |
1213 \subsubsection{Generative Constructors} | 1213 \subsubsection{Generative Constructors} |
1214 \LMLabel{generativeConstructors} | 1214 \LMLabel{generativeConstructors} |
1215 | 1215 |
1216 \LMHash{} | 1216 \LMHash{} |
1217 A {\em generative constructor} consists of a constructor name, a constructor par ameter list, and either a redirect clause or an initializer list and an optiona l body. | 1217 A {\em generative constructor} is executed to initialize a freshly allocated obj ect. |
1218 It consists of a constructor name, a constructor parameter list, and either a re direct clause or an initializer list and an optional body. | |
1218 | 1219 |
1219 \begin{grammar} | 1220 \begin{grammar} |
1220 {\bf constructorSignature:} | 1221 {\bf constructorSignature:} |
1221 identifier (`{\escapegrammar .}' identifier)? formalParameterList | 1222 identifier (`{\escapegrammar .}' identifier)? formalParameterList |
1222 . | 1223 . |
1223 \end{grammar} | 1224 \end{grammar} |
1224 | 1225 |
1225 \LMHash{} | 1226 \LMHash{} |
1226 A {\em constructor parameter list} is a parenthesized, comma-separated list of f ormal constructor parameters. A {\em formal constructor parameter} is either a f ormal parameter (\ref{formalParameters}) or an initializing formal. An {\em init ializing formal} has the form \code{\THIS{}.id}, where \code{id} is the name of an instance variable of the immediately enclosing class. It is a compile-time e rror if \code{id} is not an instance variable of the immediately enclosing class . It is a compile-time error if an initializing formal is used by a function oth er than a non-redirecting generative constructor. | 1227 A {\em constructor parameter list} is a parenthesized, comma-separated list of f ormal constructor parameters. A {\em formal constructor parameter} is either a f ormal parameter (\ref{formalParameters}) or an initializing formal. An {\em init ializing formal} has the form \code{\THIS{}.id}, where \code{id} is the name of an instance variable of the immediately enclosing class. It is a compile-time e rror if \code{id} is not an instance variable of the immediately enclosing class . It is a compile-time error if an initializing formal is used by a function oth er than a non-redirecting generative constructor. |
1227 | 1228 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1279 | 1280 |
1280 \LMHash{} | 1281 \LMHash{} |
1281 A generative constructor may be {\em redirecting}, in which case its only action is to invoke another generative constructor. A redirecting constructor has no body; instead, it has a redirect clause that specifies which constructor the inv ocation is redirected to, and with what arguments. | 1282 A generative constructor may be {\em redirecting}, in which case its only action is to invoke another generative constructor. A redirecting constructor has no body; instead, it has a redirect clause that specifies which constructor the inv ocation is redirected to, and with what arguments. |
1282 | 1283 |
1283 \begin{grammar} | 1284 \begin{grammar} |
1284 {\bf redirection:} | 1285 {\bf redirection:} |
1285 `{\escapegrammar :}' \THIS{} (`{\escapegrammar .}' identifier)? arguments | 1286 `{\escapegrammar :}' \THIS{} (`{\escapegrammar .}' identifier)? arguments |
1286 . | 1287 . |
1287 \end{grammar} | 1288 \end{grammar} |
1288 | 1289 |
1290 A redirecting generative constructor is executed to initialize an object $o$ as | |
1291 follows: | |
1292 | |
1293 Let $C$ be the class containing the redirecting generative constructor. | |
1294 Let $k$ the target generative constructor specified by either \THIS{} (the const ructor named $C$) or $\THIS{}.id$ (the constructor named $C.id$). | |
1295 Evaluate \code{arguments} to an argument list. | |
1296 Then bind the argument list to the formal parameters of $k$ and | |
1297 execute $k$ on the fresh object $o$. | |
1298 | |
1299 | |
1289 % Need to specify exactly how executing a redirecting constructor works | 1300 % Need to specify exactly how executing a redirecting constructor works |
1290 | 1301 |
1291 | 1302 |
1292 %\Q{We now have generative constructors with no bodies as well.} | 1303 %\Q{We now have generative constructors with no bodies as well.} |
1293 | 1304 |
1294 \paragraph{Initializer Lists} | 1305 \paragraph{Initializer Lists} |
1295 \LMLabel{initializerLists} | 1306 \LMLabel{initializerLists} |
1296 | 1307 |
1297 \LMHash{} | 1308 \LMHash{} |
1298 An initializer list begins with a colon, and consists of a comma-separated list of individual {\em initializers}. There are two kinds of initializers. | 1309 An initializer list begins with a colon, and consists of a comma-separated list of individual {\em initializers}. There are two kinds of initializers. |
(...skipping 20 matching lines...) Expand all Loading... | |
1319 | 1330 |
1320 \end{grammar} | 1331 \end{grammar} |
1321 | 1332 |
1322 \LMHash{} | 1333 \LMHash{} |
1323 Let $k$ be a generative constructor. Then $k$ may include at most one superini tializer in its initializer list or a compile-time error occurs. If no superinit ializer is provided, an implicit superinitializer of the form \SUPER{}() is adde d at the end of $k$'s initializer list, unless the enclosing class is class \cod e{Object}. It is a compile-time error if more than one initializer corresponding to a given instance variable appears in $k$'s initializer list. It is a compile -time error if $k$'s initializer list contains an initializer for a variable tha t is initialized by means of an initializing formal of $k$. % It is a compile-ti me error if $k$'s initializer list contains an initializer for a final variable $f$ whose declaration includes an initialization expression. | 1334 Let $k$ be a generative constructor. Then $k$ may include at most one superini tializer in its initializer list or a compile-time error occurs. If no superinit ializer is provided, an implicit superinitializer of the form \SUPER{}() is adde d at the end of $k$'s initializer list, unless the enclosing class is class \cod e{Object}. It is a compile-time error if more than one initializer corresponding to a given instance variable appears in $k$'s initializer list. It is a compile -time error if $k$'s initializer list contains an initializer for a variable tha t is initialized by means of an initializing formal of $k$. % It is a compile-ti me error if $k$'s initializer list contains an initializer for a final variable $f$ whose declaration includes an initialization expression. |
1324 | 1335 |
1325 \LMHash{} | 1336 \LMHash{} |
1326 Each final instance variable $f$ declared in the immediately enclosing class mus t have an initializer in $k$'s initializer list unless it has already been initi alized by one of the following means: | 1337 Each final instance variable $f$ declared in the immediately enclosing class mus t have an initializer in $k$'s initializer list unless it has already been initi alized by one of the following means: |
1327 \begin{itemize} | 1338 \begin{itemize} |
1328 \item Initialization at the declaration of $f$. | 1339 \item Initialization at the declaration of $f$. |
1329 \item Initialization by means of an initializing formal of $k$. | 1340 \item Initialization by means of an initializing formal of $k$. |
1330 \end{itemize} | 1341 \end{itemize} |
1331 | 1342 |
1332 or a static warning occurs. It is a compile-time error if $k$'s initializer list contains an initializer for a variable that is not an instance variable declare d in the immediately surrounding class. | 1343 or a static warning occurs. It is a compile-time error if $k$'s initializer list contains an initializer for a variable that is not an instance variable declare d in the immediately surrounding class. |
1333 | 1344 |
1334 | 1345 |
1335 \commentary{The initializer list may of course contain an initializer for any instance variable declared by the immediately surrounding class, even if it is n ot final. | 1346 \commentary{The initializer list may of course contain an initializer for any instance variable declared by the immediately surrounding class, even if it is n ot final. |
1336 } | 1347 } |
1337 | 1348 |
1338 \LMHash{} | 1349 \LMHash{} |
1339 It is a compile-time error if a generative constructor of class \code{Object} includes a superinitializer. | 1350 It is a compile-time error if a generative constructor of class \code{Object} includes a superinitializer. |
1340 | 1351 |
1341 \LMHash{} | 1352 \LMHash{} |
1342 Execution of a generative constructor $k$ is always done with respect to a set o f bindings for its formal parameters and with \THIS{} bound to a fresh instance $i$ and the type parameters of the immediately enclosing class bound to a set o f actual type arguments $V_1, \ldots , V_m$. | 1353 Execution of a generative constructor $k$ to initialize a fresh instance $i$ |
1354 is always done with respect to a set of bindings for its formal parameters | |
1355 and the type parameters of the immediately enclosing class bound to a set of act ual type arguments $V_1, \ldots , V_m$. | |
1343 | 1356 |
1344 \commentary{These bindings are usually determined by the instance creation expre ssion that invoked the constructor (directly or indirectly). However, they may a lso be determined by a reflective call,. | 1357 \commentary{These bindings are usually determined by the instance creation expre ssion that invoked the constructor (directly or indirectly). However, they may a lso be determined by a reflective call,. |
1345 } | 1358 } |
1346 | 1359 |
1360 | |
1347 \LMHash{} | 1361 \LMHash{} |
1348 If $k$ is redirecting then its redirect clause has the form | 1362 If $k$ is redirecting then its redirect clause has the form |
1349 | 1363 |
1350 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 1364 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
1351 | 1365 |
1352 where $g$ identifies another generative constructor of the immediately surround ing class. Then execution of $k$ proceeds by evaluating the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, and then executing $g$ with respect to the bindings resulting from the evaluation of $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ and with \THIS{} bound to $i$ and the type parameters of the immediately enclosing class bound to $V_1, \ ldots , V_m$. | 1366 where $g$ identifies another generative constructor of the immediately surround ing class. Then execution of $k$ to initialize $i$ proceeds by evaluating the ar gument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, and then executing $g$ to initialize $i$ with respect to the bindings resulting from the evaluation of $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ and with \THIS{} bound to $i$ and the type parameters of the immediat ely enclosing class bound to $V_1, \ldots , V_m$. |
1353 | 1367 |
1354 \LMHash{} | 1368 \LMHash{} |
1355 Otherwise, execution proceeds as follows: | 1369 Otherwise, execution proceeds as follows: |
1356 | 1370 |
1357 \LMHash{} | 1371 \LMHash{} |
1358 %First, a fresh instance (\ref{generativeConstructors}) $i$ of the immediately e nclosing class is allocated. Next, the instance variable declarations of the im mediately enclosing class are visited in the order they appear in the program te xt. For each such declaration $d$, if $d$ has the form \code{$finalConstVarOrTy pe$ $v$ = $e$; } then the instance variable $v$ of $i$ is bound to the value of $e$ (which is necessarily a compile-time constant). | 1372 %First, a fresh instance (\ref{generativeConstructors}) $i$ of the immediately e nclosing class is allocated. |
1373 | |
1374 The instance variable declarations of the immediately enclosing class are visite d in the order they appear in the program text. | |
1375 For each such declaration $d$, if $d$ has the form \code{$finalConstVarOrType$ $ v$ = $e$; } | |
1376 then $e$ is evaluated to an object $o$ | |
1377 and the instance variable $v$ of $i$ is bound to $o$. | |
1378 | |
1359 %Next, a | 1379 %Next, a |
1360 Any initializing formals declared in $k$'s parameter list are executed in the or der they appear in the program text. | 1380 Any initializing formals declared in $k$'s parameter list are executed in the or der they appear in the program text. |
1361 % In fact, this order is unobservable; this could be done any time prior to runn ing the body, since | 1381 % In fact, this order is unobservable; this could be done any time prior to runn ing the body, since |
1362 % these only effect \THIS{}. | 1382 % these only effect \THIS{}. |
1363 Then, $k$'s initializers are executed in the order they appear in the program. | 1383 Then, $k$'s initializers are executed to initialize $i$ |
1384 in the order they appear in the program. | |
1364 | 1385 |
1365 \rationale {We could observe the order by side effecting external routines call ed. So we need to specify the order.} | 1386 \rationale {We could observe the order by side effecting external routines calle d. So we need to specify the order.} |
1387 | |
1388 Then if any instance variable of $i$ declared by the immediately enclosing class | |
1389 is not yet bound to a value, | |
1390 it is a dynamic error if such a variable is a \FINAL{} variable, | |
1391 otherwise all such variables are initialized with the \NULL{} value. | |
1392 | |
1393 After this, unless the enclosing class is \code{Object}, the super constructor c all implicitly or explicitly specified in $k$'s initializers, is now executed to further initialize $i$, as specified below. | |
1394 | |
1395 \commentary{ | |
1396 The super constructor call can be written anywhere in the initializers of $k$, b ut the actual call always happens after all initializers have been processed. | |
1397 It is not equivalent to moving the super call to the end of the initializers | |
1398 because the argument expressions may have visible side effects | |
1399 which must happen in the order the expressions occur in the program text. | |
1400 } | |
1366 | 1401 |
1367 \LMHash{} | 1402 \LMHash{} |
1368 After all the initializers have completed, the body of $k$ is executed in a sc ope where \THIS{} is bound to $i$. Execution of the body begins with execution o f the body of the superconstructor with \THIS{} bound to $i$, the type paramete rs of the immediately enclosing class bound to a set of actual type arguments $V _1, \ldots , V_m$ and the formal parameters bindings determined by the argument list of the superinitializer of $k$. | 1403 After all superclass constructors have completed, the body of $k$ is executed in a scope where \THIS{} is bound to $i$. |
1369 | 1404 |
1370 \rationale{ | 1405 \rationale{ |
1371 This process ensures that no uninitialized final field is ever seen by code. Not e that \THIS{} is not in scope on the right hand side of an initializer (see \re f{this}) so no instance method can execute during initialization: an instance me thod cannot be directly invoked, nor can \THIS{} be passed into any other code being invoked in the initializer. | 1406 This process ensures that no uninitialized final field is ever seen by code. Not e that \THIS{} is not in scope on the right hand side of an initializer (see \re f{this}) so no instance method can execute during initialization: an instance me thod cannot be directly invoked, nor can \THIS{} be passed into any other code being invoked in the initializer. |
1372 } | 1407 } |
1373 | 1408 |
1374 \LMHash{} | 1409 \LMHash{} |
1375 Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} proceeds as fol lows: | 1410 Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} to initialize a n object $i$ proceeds as follows: |
1376 | 1411 |
1377 \LMHash{} | 1412 \LMHash{} |
1378 First, the expression $e$ is evaluated to an object $o$. Then, the instance vari able $v$ of the object denoted by \THIS{} is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occur s. In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the int erface of the class of $o$ is not a subtype of the actual type of the field $v$. | 1413 First, the expression $e$ is evaluated to an object $o$. Then, the instance vari able $v$ of $i$ is bound to $o$, unless $v$ is a final variable that has already been initialized, in which case a runtime error occurs. 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 the field $v$. |
1379 | 1414 |
1380 \LMHash{} | 1415 \LMHash{} |
1381 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t he form \code{\THIS{}.$v$ = $e$}. | 1416 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t he form \code{\THIS{}.$v$ = $e$}. |
1382 | 1417 |
1383 \LMHash{} | 1418 \LMHash{} |
1384 Execution of a superinitializer of the form | 1419 Execution of a superinitializer of the form |
1385 | 1420 |
1386 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ | 1421 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ |
1387 | 1422 |
1388 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ | 1423 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ |
1389 | 1424 |
1390 proceeds as follows: | 1425 proceeds as follows: |
1391 | 1426 |
1392 \LMHash{} | 1427 \LMHash{} |
1393 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ is evaluated. | 1428 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ is evaluated. |
1429 This evaluated argument list is remembered until after the entire initializer li st has been evaluated, at which point the constructor is executed as follows: | |
1394 | 1430 |
1395 \LMHash{} | 1431 \LMHash{} |
1396 Let $C$ be the class in which the superinitializer appears and let $S$ be the su perclass of $C$. If $S$ is generic (\ref{generics}), let $U_1, , \ldots, U_m$ b e the actual type arguments passed to $S$ in the superclass clause of $C$. | 1432 Let $C$ be the class in which the superinitializer appears and let $S$ be the su perclass of $C$. If $S$ is generic (\ref{generics}), let $U_1, , \ldots, U_m$ b e the actual type arguments passed to $S$ in the superclass clause of $C$. |
1397 | 1433 |
1398 \LMHash{} | 1434 \LMHash{} |
1399 Then, the initializer list of the constructor $S$ (respectively $S.id$) is execu ted with respect to the bindings that resulted from the evaluation of the argume nt list, with \THIS{} bound to the current binding of \THIS{}, and the type pa rameters (if any) of class $S$ bound to the current bindings of $U_1, , \ldots, U_m$. | 1435 The generative constructor $S$ (respectively $S.id$) of $S$ is executed to initi alize $i$ with respect to the bindings that resulted from the evaluation of the argument list, and the type parameters (if any) of class $S$ bound to the curren t bindings of $U_1, , \ldots, U_m$. |
1400 | 1436 |
1401 \LMHash{} | 1437 \LMHash{} |
1402 It is a compile-time error if class $S$ does not declare a generative constructo r named $S$ (respectively $S.id$). | 1438 It is a compile-time error if class $S$ does not declare a generative constructo r named $S$ (respectively $S.id$). |
1403 | 1439 |
1404 \subsubsection{Factories} | 1440 \subsubsection{Factories} |
1405 \LMLabel{factories} | 1441 \LMLabel{factories} |
1406 | 1442 |
1407 \LMHash{} | 1443 \LMHash{} |
1408 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden tifierReference}) \FACTORY{}. | 1444 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden tifierReference}) \FACTORY{}. |
1409 | 1445 |
(...skipping 12 matching lines...) Expand all Loading... | |
1422 \LMHash{} | 1458 \LMHash{} |
1423 It is a compile-time error if $M$ is not the name of the immediately enclosing c lass. | 1459 It is a compile-time error if $M$ is not the name of the immediately enclosing c lass. |
1424 | 1460 |
1425 \LMHash{} | 1461 \LMHash{} |
1426 In checked mode, it is a dynamic type error if a factory returns a non-null obje ct whose type is not a subtype of its actual (\ref{actualTypeOfADeclaration}) re turn type. | 1462 In checked mode, it is a dynamic type error if a factory returns a non-null obje ct whose type is not a subtype of its actual (\ref{actualTypeOfADeclaration}) re turn type. |
1427 | 1463 |
1428 \rationale{It seems useless to allow a factory to return null. But it is more un iform to allow it, as the rules currently do.} | 1464 \rationale{It seems useless to allow a factory to return null. But it is more un iform to allow it, as the rules currently do.} |
1429 | 1465 |
1430 \rationale{Factories address classic weaknesses associated with constructors in other languages. | 1466 \rationale{Factories address classic weaknesses associated with constructors in other languages. |
1431 Factories can produce instances that are not freshly allocated: they can come fr om a cache. Likewise, factories can return instances of different classes. | 1467 Factories can produce instances that are not freshly allocated: they can come fr om a cache. Likewise, factories can return instances of different classes. |
1432 | |
1433 } | 1468 } |
1434 | 1469 |
1435 \paragraph{Redirecting Factory Constructors} | 1470 \paragraph{Redirecting Factory Constructors} |
1436 \LMLabel{redirectingFactoryConstructors} | 1471 \LMLabel{redirectingFactoryConstructors} |
1437 | 1472 |
1438 \LMHash{} | 1473 \LMHash{} |
1439 A {\em redirecting factory constructor} specifies a call to a constructor of ano ther class that is to be used whenever the redirecting constructor is called. | 1474 A {\em redirecting factory constructor} specifies a call to a constructor of ano ther class that is to be used whenever the redirecting constructor is called. |
1440 | 1475 |
1441 \begin{grammar} | 1476 \begin{grammar} |
1442 {\bf redirectingFactoryConstructorSignature:} | 1477 {\bf redirectingFactoryConstructorSignature:} |
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2332 \LMHash{} | 2367 \LMHash{} |
2333 The constant expression given in an annotation is type checked and evaluated in the scope surrounding the declaration being annotated. | 2368 The constant expression given in an annotation is type checked and evaluated in the scope surrounding the declaration being annotated. |
2334 | 2369 |
2335 | 2370 |
2336 \section{Expressions} | 2371 \section{Expressions} |
2337 \LMLabel{expressions} | 2372 \LMLabel{expressions} |
2338 | 2373 |
2339 \LMHash{} | 2374 \LMHash{} |
2340 An {\em expression} is a fragment of Dart code that can be evaluated at run time to yield a {\em value}, which is always an object. Every expression has an asso ciated static type (\ref{staticTypes}). Every value has an associated dynamic ty pe (\ref{dynamicTypeSystem}). | 2375 An {\em expression} is a fragment of Dart code that can be evaluated at run time to yield a {\em value}, which is always an object. Every expression has an asso ciated static type (\ref{staticTypes}). Every value has an associated dynamic ty pe (\ref{dynamicTypeSystem}). |
2341 | 2376 |
2377 Expressions can also {\em throw} an exception object and an associated stack tra ce. | |
2378 | |
2379 Evaluation of an expression will always either {\em yield a value} or it will {\ em throw an exception} along with an associated stack trace. | |
2380 | |
2381 If evaluation of an expression is defined in terms of evaluation of another | |
2382 expression, and the evaluation of the other expression throws an exception, | |
2383 if nothing else is stated, the evaluation of the first expression stops | |
2384 at that point and throws the same exception. | |
2385 | |
2342 | 2386 |
2343 \begin{grammar} | 2387 \begin{grammar} |
2344 | 2388 |
2345 {\bf expression:}assignableExpression assignmentOperator expression; | 2389 {\bf expression:}assignableExpression assignmentOperator expression; |
2346 conditionalExpression cascadeSection*; | 2390 conditionalExpression cascadeSection*; |
2347 throwExpression | 2391 throwExpression |
2348 . | 2392 . |
2349 | 2393 |
2350 | 2394 |
2351 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio nWithoutCascade; | 2395 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio nWithoutCascade; |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2534 listLiteral | 2578 listLiteral |
2535 . | 2579 . |
2536 \end{grammar} | 2580 \end{grammar} |
2537 | 2581 |
2538 | 2582 |
2539 | 2583 |
2540 \subsection{Null} | 2584 \subsection{Null} |
2541 \LMLabel{null} | 2585 \LMLabel{null} |
2542 | 2586 |
2543 \LMHash{} | 2587 \LMHash{} |
2544 The reserved word \NULL{} denotes the {\em null object}. | 2588 The reserved word \NULL{} denotes the {\em null object}. |
Kevin Millikin (Google)
2016/10/13 12:18:37
"denotes" ==> "evaluates to"
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Done.
| |
2545 %\Q{Any methods, such as \code{isNull}?} | 2589 %\Q{Any methods, such as \code{isNull}?} |
2546 | 2590 |
2547 \begin{grammar} | 2591 \begin{grammar} |
2548 {\bf nullLiteral:} | 2592 {\bf nullLiteral:} |
2549 \NULL{} | 2593 \NULL{} |
2550 . | 2594 . |
2551 \end{grammar} | 2595 \end{grammar} |
2552 | 2596 |
2553 \LMHash{} | 2597 \LMHash{} |
2554 The null object is the sole instance of the built-in class \code{Null}. Attempti ng to instantiate \code{Null} causes a run-time error. It is a compile-time erro r for a class to attempt to extend, mix in or implement \code{Null}. | 2598 The null object is the sole instance of the built-in class \code{Null}. Attempti ng to instantiate \code{Null} causes a run-time error. It is a compile-time erro r for a class to attempt to extend, mix in or implement \code{Null}. |
(...skipping 29 matching lines...) Expand all Loading... | |
2584 `0X' HEX\_DIGIT+ | 2628 `0X' HEX\_DIGIT+ |
2585 . | 2629 . |
2586 | 2630 |
2587 {\bf HEX\_DIGIT:}`a'{\escapegrammar ..}'f'; | 2631 {\bf HEX\_DIGIT:}`a'{\escapegrammar ..}'f'; |
2588 `A'{\escapegrammar ..}'F'; | 2632 `A'{\escapegrammar ..}'F'; |
2589 DIGIT | 2633 DIGIT |
2590 . | 2634 . |
2591 \end{grammar} | 2635 \end{grammar} |
2592 | 2636 |
2593 \LMHash{} | 2637 \LMHash{} |
2594 If a numeric literal begins with the prefix `0x' or `0X', it denotes the hexadec imal integer represented by the part of the literal following `0x' (respectively `0X'). Otherwise, if the numeric literal contains only decimal digits, it denot es a decimal integer. Otherwise, the numeric literal contains either a decimal point or an exponent part and it denotes a 64 bit double precision floating poin t number as specified by the IEEE 754 standard. | 2638 If a numeric literal begins with the prefix `0x' or `0X', it denotes the hexadec imal integer represented by the part of the literal following `0x' (respectively `0X'). Otherwise, if the numeric literal contains only decimal digits, it denot es a decimal integer. Otherwise, the numeric literal contains either a decimal point or an exponent part and it denotes a 64 bit double precision floating poin t number as specified by the IEEE 754 standard. |
Kevin Millikin (Google)
2016/10/13 12:18:38
"denotes" => "evaluates to"
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Rewritten entire section. Not sure it makes comple
| |
2595 | 2639 |
2596 \LMHash{} | 2640 \LMHash{} |
2597 In principle, the range of integers supported by a Dart implementations is unlim ited. In practice, it is limited by available memory. Implementations may also b e limited by other considerations. | 2641 In principle, the range of integers supported by a Dart implementations is unlim ited. In practice, it is limited by available memory. Implementations may also b e limited by other considerations. |
2598 | 2642 |
2599 \commentary{ | 2643 \commentary{ |
2600 For example, implementations may choose to limit the range to facilitate efficie nt compilation to Javascript. These limitations should be relaxed as soon as tec hnologically feasible. | 2644 For example, implementations may choose to limit the range to facilitate efficie nt compilation to Javascript. These limitations should be relaxed as soon as tec hnologically feasible. |
2601 } | 2645 } |
2602 | 2646 |
2603 \LMHash{} | 2647 \LMHash{} |
2604 It is a compile-time error for a class to attempt to extend, mix in or implement \code{int}. It is a compile-time error for a class to attempt to extend, mix in or implement \code{double}. It is a compile-time error for any type other than the types \code{int} and \code{double} to attempt to extend, mix in or implement \code{num}. | 2648 It is a compile-time error for a class to attempt to extend, mix in or implement \code{int}. It is a compile-time error for a class to attempt to extend, mix in or implement \code{double}. It is a compile-time error for any type other than the types \code{int} and \code{double} to attempt to extend, mix in or implement \code{num}. |
2605 | 2649 |
2606 \LMHash{} | 2650 \LMHash{} |
2607 An {\em integer literal} is either a hexadecimal integer literal or a decimal i nteger literal. Invoking the getter \code{runtimeType} on an integer literal ret urns the \code{Type} object that is the value of the expression \code{int}. The static type of an integer literal is \code{int}. | 2651 An {\em integer literal} is either a hexadecimal integer literal or a decimal i nteger literal. Invoking the getter \code{runtimeType} on an integer literal ret urns the \code{Type} object that is the value of the expression \code{int}. The static type of an integer literal is \code{int}. |
Kevin Millikin (Google)
2016/10/13 12:18:37
Definitely outside the scope of this change: do we
Lasse Reichstein Nielsen
2016/10/17 10:08:23
It should apply to all integers, and the spec is i
eernst
2016/10/19 13:37:04
I actually think the spec carefully tries to _avoi
| |
2608 | 2652 |
2609 \LMHash{} | 2653 \LMHash{} |
2610 A {\em literal double} is a numeric literal that is not an integer literal. Invo king the getter \code{runtimeType} on a literal double returns the \code{Type} o bject that is the value of the expression \code{double}. | 2654 A {\em literal double} is a numeric literal that is not an integer literal. Invo king the getter \code{runtimeType} on a literal double returns the \code{Type} o bject that is the value of the expression \code{double}. |
2611 The static type of a literal double is \code{double}. | 2655 The static type of a literal double is \code{double}. |
2612 | 2656 |
2613 \subsection{Booleans} | 2657 \subsection{Booleans} |
2614 \LMLabel{booleans} | 2658 \LMLabel{booleans} |
2615 | 2659 |
2616 \LMHash{} | 2660 \LMHash{} |
2617 The reserved words \TRUE{} and \FALSE{} denote objects that represent the boolea n values true and false respectively. They are the {\em boolean literals}. | 2661 The reserved words \TRUE{} and \FALSE{} denote objects that represent the boolea n values true and false respectively. They are the {\em boolean literals}. |
Kevin Millikin (Google)
2016/10/13 12:18:36
"denote" => "evaluate to"
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Rewritten to distinguish syntax from `bool` instan
| |
2618 | 2662 |
2619 \begin{grammar} | 2663 \begin{grammar} |
2620 {\bf booleanLiteral:}\TRUE{}; | 2664 {\bf booleanLiteral:}\TRUE{}; |
2621 \FALSE{} | 2665 \FALSE{} |
2622 . | 2666 . |
2623 \end{grammar} | 2667 \end{grammar} |
2624 | 2668 |
2625 \LMHash{} | 2669 \LMHash{} |
2626 Both \TRUE{} and \FALSE{} implement the built-in class \code{bool}. It is a co mpile-time error for a class to attempt to extend, mix in or implement\code{ boo l}. | 2670 Both \TRUE{} and \FALSE{} implement the built-in class \code{bool}. It is a co mpile-time error for a class to attempt to extend, mix in or implement\code{ boo l}. |
Kevin Millikin (Google)
2016/10/13 12:18:37
A class can implement an interface and we sometime
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Changed to "are instances of".
The spec is a litt
| |
2627 | 2671 |
2628 \commentary{ | 2672 \commentary{ |
2629 It follows that the two boolean literals are the only two instances of \code{boo l}. | 2673 It follows that the two boolean literals are the only two instances of \code{boo l}. |
2630 } | 2674 } |
2631 | 2675 |
2632 \LMHash{} | 2676 \LMHash{} |
2633 Invoking the getter \code{runtimeType} on a boolean literal returns the \code{Ty pe} object that is the value of the expression \code{bool}. The static type of a boolean literal is \code{bool}. | 2677 Invoking the getter \code{runtimeType} on a boolean literal returns the \code{Ty pe} object that is the value of the expression \code{bool}. The static type of a boolean literal is \code{bool}. |
Kevin Millikin (Google)
2016/10/13 12:18:37
"literal" ==> "value" or "object"?
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Removed.
| |
2634 | 2678 |
2635 \subsubsection{Boolean Conversion} | 2679 \subsubsection{Boolean Conversion} |
2636 \LMLabel{booleanConversion} | 2680 \LMLabel{booleanConversion} |
2637 | 2681 |
2638 \LMHash{} | 2682 \LMHash{} |
2639 {\em Boolean conversion} maps any object $o$ into a boolean. Boolean conversion is defined by the function application | 2683 {\em Boolean conversion} maps any object $o$ into a boolean. Boolean conversion is defined by the function application |
2640 | 2684 |
2641 \begin{dartCode} | 2685 \begin{dartCode} |
2642 (bool v)\{ | 2686 (bool v)\{ |
2643 \ASSERT{}(v != \NULL{}); | 2687 \ASSERT{}(v != \NULL{}); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2824 stringInterpolation | 2868 stringInterpolation |
2825 . | 2869 . |
2826 | 2870 |
2827 {\bf NEWLINE:}$\backslash$ n; | 2871 {\bf NEWLINE:}$\backslash$ n; |
2828 $\backslash$ r | 2872 $\backslash$ r |
2829 . | 2873 . |
2830 | 2874 |
2831 \end{grammar} | 2875 \end{grammar} |
2832 | 2876 |
2833 \LMHash{} | 2877 \LMHash{} |
2834 All string literals implement the built-in class \code{String}. It is a compile- time error for a class to attempt to extend, mix in or implement \code{String}. Invoking the getter \code{runtimeType} on a string literal returns the \code{Typ e} object that is the value of the expression \code{String}. The static type of a string literal is \code{String}. | 2878 All string literals implement the built-in class \code{String}. It is a compile- time error for a class to attempt to extend, mix in or implement \code{String}. Invoking the getter \code{runtimeType} on a string literal returns the \code{Typ e} object that is the value of the expression \code{String}. The static type of a string literal is \code{String}. |
Kevin Millikin (Google)
2016/10/13 12:18:36
A literal can't implement an interface. A literal
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Done.
| |
2835 | 2879 |
2836 \subsubsection{String Interpolation} | 2880 \subsubsection{String Interpolation} |
2837 \LMLabel{stringInterpolation} | 2881 \LMLabel{stringInterpolation} |
2838 | 2882 |
2839 \LMHash{} | 2883 \LMHash{} |
2840 It is possible to embed expressions within non-raw string literals, such that th ese expressions are evaluated, and the resulting values are converted into strin gs and concatenated with the enclosing string. This process is known as {\em str ing interpolation}. | 2884 It is possible to embed expressions within non-raw string literals, such that th ese expressions are evaluated, and the resulting values are converted into strin gs and concatenated with the enclosing string. This process is known as {\em str ing interpolation}. |
2841 | 2885 |
2842 \begin{grammar} | 2886 \begin{grammar} |
2843 {\bf stringInterpolation:}`\$' IDENTIFIER\_NO\_DOLLAR; | 2887 {\bf stringInterpolation:}`\$' IDENTIFIER\_NO\_DOLLAR; |
2844 `\$' `\{' expression `\}' % could be top level expression, no? | 2888 `\$' `\{' expression `\}' % could be top level expression, no? |
2845 . | 2889 . |
2846 \end{grammar} | 2890 \end{grammar} |
2847 | 2891 |
2848 \commentary{The reader will note that the expression inside the interpolation co uld itself include strings, which could again be interpolated recursively. | 2892 \commentary{The reader will note that the expression inside the interpolation co uld itself include strings, which could again be interpolated recursively. |
2849 } | 2893 } |
2850 | 2894 |
2851 \LMHash{} | 2895 \LMHash{} |
2852 An unescaped \$ character in a string signifies the beginning of an interpolated expression. The \$ sign may be followed by either: | 2896 An unescaped \$ character in a string signifies the beginning of an interpolated expression. The \$ sign may be followed by either: |
2853 \begin{itemize} | 2897 \begin{itemize} |
2854 \item A single identifier $id$ that must not contain the \$ character. | 2898 \item A single identifier $id$ that must not contain the \$ character. |
2855 \item An expression $e$ delimited by curly braces. | 2899 \item An expression $e$ delimited by curly braces. |
2856 \end{itemize} | 2900 \end{itemize} |
2857 | 2901 |
2858 \LMHash{} | 2902 \LMHash{} |
2859 The form \code{\$id} is equivalent to the form \code{\$\{id\}}. An interpolated string \code{`$s_1$\$\{$e$\}$s_2$'} is equivalent to the concatenation of the strings \code{`$s_1$'}, \code{$e$.toString()} and \code{$`s_2$'}. Likewise an interpolated string \code{``$s_1$\$\{e\}$s_2$''} is equivalent to the concatena tion of the strings \code{``$s_1$''}, \code{$e$.toString()} and \code{``$s_2$'' }. | 2903 The form \code{\$id} is equivalent to the form \code{\$\{id\}}. An interpolated string \code{`$s_1$\$\{$e$\}$s_2$'} is equivalent to the concatenation of the strings \code{`$s_1$'}, \code{$e$.toString()} and \code{$`s_2$'}. Likewise an interpolated string \code{``$s_1$\$\{e\}$s_2$''} is equivalent to the concatena tion of the strings \code{``$s_1$''}, \code{$e$.toString()} and \code{``$s_2$'' }. |
Kevin Millikin (Google)
2016/10/13 12:18:36
Note that this doesn't explicitly impose a left-to
Lasse Reichstein Nielsen
2016/10/17 10:08:23
And it doesn't cover the case where e.toString doe
| |
2860 | 2904 |
2861 \subsection{Symbols} | 2905 \subsection{Symbols} |
2862 \LMLabel{symbols} | 2906 \LMLabel{symbols} |
2863 | 2907 |
2864 \LMHash{} | 2908 \LMHash{} |
2865 A {\em symbol literal} denotes the name of a declaration in a Dart program. | 2909 A {\em symbol literal} denotes the name of a declaration in a Dart program. |
2866 | 2910 |
2867 \begin{grammar} | 2911 \begin{grammar} |
2868 {\bf symbolLiteral:} | 2912 {\bf symbolLiteral:} |
2869 `\#' (operator $|$ (identifier (`{\escapegrammar .}' identifier)*)) . | 2913 `\#' (operator $|$ (identifier (`{\escapegrammar .}' identifier)*)) . |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3038 \THROW{} expression | 3082 \THROW{} expression |
3039 . | 3083 . |
3040 | 3084 |
3041 {\bf throwExpressionWithoutCascade:} | 3085 {\bf throwExpressionWithoutCascade:} |
3042 \THROW{} expressionWithoutCascade | 3086 \THROW{} expressionWithoutCascade |
3043 . | 3087 . |
3044 | 3088 |
3045 \end{grammar} | 3089 \end{grammar} |
3046 | 3090 |
3047 \LMHash{} | 3091 \LMHash{} |
3048 The {\em current exception} is the last exception raised and not subsequently c aught at a given moment during runtime. | 3092 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as f ollows: |
3049 | |
3050 \LMHash{} | |
3051 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as follows: | |
3052 | 3093 |
3053 \LMHash{} | 3094 \LMHash{} |
3054 The expression $e$ is evaluated yielding a value $v$. | 3095 The expression $e$ is evaluated yielding a value $v$. |
3055 | 3096 |
3056 \commentary{ | 3097 \commentary{ |
3057 There is no requirement that the expression $e$ evaluate to a special kind of ex ception or error object. | 3098 There is no requirement that the expression $e$ evaluate to a special kind of ex ception or error object. |
3058 } | 3099 } |
3059 | 3100 |
3060 \LMHash{} | 3101 \LMHash{} |
3061 If $e$ evaluates to \NULL{} (\ref{null}), then a \code{NullThrownError} is throw n. Otherwise the current exception is set to $v$ and the current return value (\ ref{return}) becomes undefined. | 3102 If $e$ evaluates to \NULL{} (\ref{null}), then a \code{NullThrownError} is throw n. Otherwise let $t$ be a stack trace corresponding to the current execution sta te, and the \THROW{} statement aborts by {\em throwing} with $e$ as exception ob ject and $t$ as stack trace. |
Kevin Millikin (Google)
2016/10/13 12:18:37
$e$ evaluates to ==> $v$ is
Throw is an expressio
Lasse Reichstein Nielsen
2016/10/17 10:08:24
-> If $v$ is the null value
(as you correctly poin
| |
3062 | |
3063 \rationale{The current exception and the current return value must never be simu ltaneously defined, as they represent mutually exclusive options for exiting the current function. | |
3064 } | |
3065 | 3103 |
3066 \LMHash{} | 3104 \LMHash{} |
3067 Let $f$ be the immediately enclosing function. | 3105 If $e$ is an instance of class \code{Error} or a subclass thereof, its \code{sta ckTrace} getter will return the stack trace captured at the point where the obje ct was first thrown. |
Kevin Millikin (Google)
2016/10/13 12:18:36
$e$ ==> $v$
Maybe captured isn't quite right, we
Lasse Reichstein Nielsen
2016/10/17 10:08:24
Rewritten.
| |
3068 | |
3069 \LMHash{} | |
3070 If $f$ is synchronous (\ref{functions}), control is transferred to the nearest d ynamically enclosing exception handler. | |
3071 | 3106 |
3072 \commentary{ | 3107 \commentary{ |
3073 If $f$ is marked \SYNC* then a dynamically enclosing exception handler encloses the call to \code{moveNext()} that initiated the evaluation of the throw express ion. | 3108 If the same \code{Error} object is thrown more than once, its \code{stackTrace} getter will return the stack trace captured the {\em first} time it was thrown. |
Kevin Millikin (Google)
2016/10/13 12:18:37
Same comment about captured.
Lasse Reichstein Nielsen
2016/10/17 10:08:23
captured->from
| |
3074 } | 3109 } |
3075 | 3110 |
3076 \LMHash{} | 3111 \LMHash{} |
3077 If $f$ is asynchronous then if there is a dynamically enclosing exception handl er $h$ (\ref{try}) introduced by the current activation, control is transferred to $h$, otherwise $f$ terminates. | |
3078 | |
3079 \rationale{ | |
3080 The rules for where a thrown exception will be handled must necessarily differ b etween the synchronous and asynchronous cases. Asynchronous functions cannot tra nsfer control to an exception handler defined outside themselves. Asynchronous generators post exceptions to their stream. Other asynchronous functions report exceptions via their future. | |
3081 } | |
3082 | |
3083 \LMHash{} | |
3084 If the object being thrown is an instance of class \code{Error} or a subclass th ereof, its \code{stackTrace} getter will return the stack trace current at the p oint where the object was first thrown. | |
3085 | |
3086 \LMHash{} | |
3087 The static type of a throw expression is $\bot$. | 3112 The static type of a throw expression is $\bot$. |
3088 | 3113 |
3089 | 3114 |
3090 \subsection{ Function Expressions} | 3115 \subsection{ Function Expressions} |
3091 \LMLabel{functionExpressions} | 3116 \LMLabel{functionExpressions} |
3092 | 3117 |
3093 \LMHash{} | 3118 \LMHash{} |
3094 A {\em function literal} is an object that encapsulates an executable unit of co de. | 3119 A {\em function literal} is an object that encapsulates an executable unit of co de. |
3095 | 3120 |
3096 \begin{grammar} | 3121 \begin{grammar} |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3338 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k} : a_{n+k})$ is evaluated. | 3363 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k} : a_{n+k})$ is evaluated. |
3339 | 3364 |
3340 \LMHash{} | 3365 \LMHash{} |
3341 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. | 3366 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs. |
3342 | 3367 |
3343 \LMHash{} | 3368 \LMHash{} |
3344 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs tractClassInstantiationError} is thrown. | 3369 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs tractClassInstantiationError} is thrown. |
3345 | 3370 |
3346 \LMHash{} | 3371 \LMHash{} |
3347 If $T$ is malformed or if $T$ is a type variable a dynamic error occurs. In che cked mode, if $T$ or any of its superclasses is malbounded a dynamic error occur s. | 3372 If $T$ is malformed or if $T$ is a type variable a dynamic error occurs. In che cked mode, if $T$ or any of its superclasses is malbounded a dynamic error occur s. |
3348 Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} is thrown. If $q$ has less than $n$ positional parameters or more than $n$ req uired parameters, or if $q$ lacks any of the keyword parameters $\{ x_{n+1}, \ld ots, x_{n+k}\}$ a \code{NoSuchMethodError} is thrown. | 3373 Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} i s thrown. If $q$ has less than $n$ positional parameters or more than $n$ requ ired parameters, or if $q$ lacks any of the keyword parameters $\{ x_{n+1}, \ldo ts, x_{n+k}\}$ a \code{NoSuchMethodError} is thrown. |
Kevin Millikin (Google)
2016/10/13 12:18:37
less ==> fewer
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Done.
| |
3349 | 3374 |
3350 \LMHash{} | 3375 \LMHash{} |
3351 Otherwise, if $q$ is a generative constructor (\ref{generativeConstructors}), th en: | 3376 Otherwise, if $q$ is a generative constructor (\ref{generativeConstructors}), th en: |
3352 | 3377 |
3353 \commentary{Note that it this point we are assured that the number of actual typ e arguments match the number of formal type parameters.} | 3378 \commentary{Note that it this point we are assured that the number of actual typ e arguments match the number of formal type parameters.} |
3354 | 3379 |
3355 \LMHash{} | 3380 \LMHash{} |
3356 A fresh instance (\ref{generativeConstructors}), $i$, of class $R$ is allocated . For each instance variable $f$ of $i$, if the variable declaration of $f$ has an initializer expression $e_f$, then $e_f$ is evaluated, with the type paramet ers (if any) of $R$ bound to the actual type arguments $V_1, \ldots, V_l$, to an object $o_f$ and $f$ is bound to $o_f$. Otherwise $f$ is bound to \NULL{}. | 3381 A fresh instance (\ref{generativeConstructors}), $i$, of class $R$ is allocated. |
3382 Then $q$ is executed to initialize $i$ with its formal parameters bound to the e valuated argument list and, if $R$ is a generic class, with its type parameters bound to $V_1 \ldots V_m$. | |
3357 | 3383 |
3358 \commentary{ | 3384 If execution of $q$ completes normally, $e$ evaluates to $i$. |
3359 Observe that \THIS{} is not in scope in $e_f$. Hence, the initialization cannot depend on other properties of the object being instantiated. | |
3360 } | |
3361 | |
3362 \LMHash{} | |
3363 Next, $q$ is executed with \THIS{} bound to $i$, the type parameters (if any) of $R$ bound to the actual type arguments $V_1, \ldots, V_l$ and the formal par ameter bindings that resulted from the evaluation of the argument list. The resu lt of the evaluation of $e$ is $i$. | |
3364 | 3385 |
3365 \LMHash{} | 3386 \LMHash{} |
3366 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: | 3387 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: |
3367 | 3388 |
3368 \LMHash{} | 3389 \LMHash{} |
3369 If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots, p_{n+k}) = c;$ or of the form $T.id(p_1, \ldots, p_{n+k}) = c;$ then the result of the evaluation of $e$ is equivalent to evaluating the expression | 3390 If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots, p_{n+k}) = c;$ or of the form $T.id(p_1, \ldots, p_{n+k}) = c;$ then the result of the evaluation of $e$ is equivalent to evaluating the expression |
3370 | 3391 |
3371 $[V_1, \ldots, V_m/T_1, \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1 }: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}. If evaluation of $q$ causes $q$ to be re-evaluated cyclically, a runtime error occurs. | 3392 $[V_1, \ldots, V_m/T_1, \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1 }: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}. If evaluation of $q$ causes $q$ to be re-evaluated cyclically, with only factory constructor redirections in-between, a runtime error occurs. |
3393 % Used to not have the "in-between" clause, which would disallow a factory const ructor redirecting to another constructor which conditionally calls the original factory constructor again with different arguments. | |
3372 | 3394 |
3373 | 3395 |
3374 \LMHash{} | 3396 \LMHash{} |
3375 Otherwise, the body of $q$ is executed with respect to the bindings that resulte d from the evaluation of the argument list and the type parameters (if any) of $ q$ bound to the actual type arguments $V_1, \ldots, V_l$ resulting in an object $i$. The result of the evaluation of $e$ is $i$. | 3397 Otherwise, the body of $q$ is executed with respect to the bindings that resulte d from the evaluation of the argument list and the type parameters (if any) of $ q$ bound to the actual type arguments $V_1, \ldots, V_l$. |
3398 If this execution {\em returns} or {\em completes normally} (\ref{completion}), | |
3399 let $i$ be the value {\em returned} by this execution, or \NULL{} if the executi on returns without a value or it completes normally. | |
3400 The result of the evaluation of $e$ is $i$. | |
3376 | 3401 |
3377 \LMHash{} | 3402 \LMHash{} |
3378 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n ot a factory constructor. | 3403 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n ot a factory constructor. |
3379 | 3404 |
3380 \commentary{The above gives precise meaning to the idea that instantiating an ab stract class leads to a warning. | 3405 \commentary{The above gives precise meaning to the idea that instantiating an ab stract class leads to a warning. |
3381 A similar clause applies to constant object creation in the next section. | 3406 A similar clause applies to constant object creation in the next section. |
3382 } | 3407 } |
3383 | 3408 |
3384 \rationale{In particular, a factory constructor can be declared in an abstract c lass and used safely, as it will either produce a valid instance or lead to a wa rning inside its own declaration. | 3409 \rationale{In particular, a factory constructor can be declared in an abstract c lass and used safely, as it will either produce a valid instance or lead to a wa rning inside its own declaration. |
3385 } | 3410 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3529 | 3554 |
3530 | 3555 |
3531 | 3556 |
3532 \subsection{ Function Invocation} | 3557 \subsection{ Function Invocation} |
3533 \LMLabel{functionInvocation} | 3558 \LMLabel{functionInvocation} |
3534 | 3559 |
3535 \LMHash{} | 3560 \LMHash{} |
3536 Function invocation occurs in the following cases: when a function expression ( \ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), when a method (\ref{methodInvocation}), getter (\ref{topLevelGetterInvocation}, \ref {propertyExtraction}) or setter (\ref{assignment}) is invoked or when a construc tor is invoked (either via instance creation (\ref{instanceCreation}), construct or redirection (\ref{redirectingConstructors}) or super initialization). The var ious kinds of function invocation differ as to how the function to be invoked, $ f$, is determined, as well as whether \THIS{} (\ref{this}) is bound. Once $f$ h as been determined, the formal parameters of $f$ are bound to corresponding actu al arguments. When the body of $f$ is executed it will be executed with the afor ementioned bindings. | 3561 Function invocation occurs in the following cases: when a function expression ( \ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), when a method (\ref{methodInvocation}), getter (\ref{topLevelGetterInvocation}, \ref {propertyExtraction}) or setter (\ref{assignment}) is invoked or when a construc tor is invoked (either via instance creation (\ref{instanceCreation}), construct or redirection (\ref{redirectingConstructors}) or super initialization). The var ious kinds of function invocation differ as to how the function to be invoked, $ f$, is determined, as well as whether \THIS{} (\ref{this}) is bound. Once $f$ h as been determined, the formal parameters of $f$ are bound to corresponding actu al arguments. When the body of $f$ is executed it will be executed with the afor ementioned bindings. |
3537 | 3562 |
3538 \LMHash{} | 3563 \LMHash{} |
3539 If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generat iveConstructors}) $o$ implementing the built-in class \code{Future} is associate d with the invocation and immediately returned to the caller. The body of $f$ is scheduled for execution at some future time. The future $o$ will complete when $f$ terminates. The value used to complete $o$ is the current return value (\ref {return}), if it is defined, and the current exception (\ref{throw}) otherwise. | 3564 If $f$ is marked \ASYNC{} (\ref{functions}), then a fresh instance (\ref{generat iveConstructors}) $o$ implementing the built-in class \code{Future} is associate d with the invocation and immediately returned to the caller. The body of $f$ is scheduled for execution at some future time. The future $o$ will complete when execution of $f$ completes (\ref{completion}). If $f$ completes by {\em returnin g} a value, that value used to complete $o$, if it {\em completes normally} or b y {\em returning} with no value, $o$ is completed with \NULL{}, and if it comple tes by {\em throwing} an exception $e$ and stack trace $t$, $o$ is completed wit h $e$ and stack trace $t$ as an error. |
Kevin Millikin (Google)
2016/10/13 12:18:37
I think this has to be "when execution of the body
Lasse Reichstein Nielsen
2016/10/17 10:08:23
I ignored the added return of section 9 because I
| |
3540 | 3565 |
3541 \LMHash{} | 3566 \LMHash{} |
3542 If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementi ng the built-in class \code{Stream} is associated with the invocation and immedi ately returned. When $s$ is listened to, execution of the body of $f$ will begin . When $f$ terminates: | 3567 If $f$ is marked \ASYNC* (\ref{functions}), then a fresh instance $s$ implementi ng the built-in class \code{Stream} is associated with the invocation and immedi ately returned. When $s$ is listened to, execution of the body of $f$ will begin . When $f$ completes: |
Kevin Millikin (Google)
2016/10/13 12:18:38
When the body of f completes. We also should find
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Done.
| |
3543 \begin{itemize} | 3568 \begin{itemize} |
3544 \item If the current return value is defined then, if $s$ has been canceled then its cancellation future is completed with \NULL{} (\ref{null}). | 3569 \item If $f$ {\em completes normally}, then if $s$ has been canceled then its ca ncellation future is completed with \NULL{} (\ref{null}). |
Kevin Millikin (Google)
2016/10/13 12:18:36
the body of f
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Done.
| |
3545 \item If the current exception $x$ is defined: | 3570 \item If $f$ {\em throws} exception $e$ and stack trace $t$: |
Kevin Millikin (Google)
2016/10/13 12:18:37
the body of f
Lasse Reichstein Nielsen
2016/10/17 10:08:24
Done.
| |
3546 \begin{itemize} | 3571 \begin{itemize} |
3547 \item $x$ is added to $s$. | 3572 \item $e$ and $t$ are added to $s$ as an error. |
3548 \item If $s$ has been canceled then its cancellation future is completed with $x$ as an error. | 3573 \item If $s$ has been canceled then its cancellation future is completed with $e$ and $t$ as an error. |
3549 \end{itemize} | 3574 \end{itemize} |
3550 \item $s$ is closed. | 3575 \item $s$ is closed. |
3551 \end{itemize} | 3576 \end{itemize} |
Kevin Millikin (Google)
2016/10/13 12:18:37
Perhaps here mention that the possibilities break,
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Done.
| |
3552 | 3577 |
3553 \rationale{ | 3578 \rationale{ |
3554 When an asynchronous generator's stream has been canceled, cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator. We choose to direct an y exceptions that occur at this time to the cancellation future rather than have them be lost. | 3579 When an asynchronous generator's stream has been canceled, cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator. We choose to direct an y exceptions that occur at this time to the cancellation future rather than have them be lost. |
3555 } | 3580 } |
3556 | 3581 |
3557 \LMHash{} | |
3558 If $f$ is asynchronous then, when $f$ terminates, any open stream subscriptions associated with any asynchronous for loops (\ref{asynchronousFor-in}) or yield- each statements (\ref{yieldEach}) executing within $f$ are canceled, in the ord er of their nesting, innermost first. | |
3559 | |
3560 \rationale{Such streams may be left open by for loops that were escaped when an exception was thrown within them for example. | |
3561 } | |
3562 | |
3563 %\LMHash{} | 3582 %\LMHash{} |
3564 %When a stream is canceled, the implementation must wait for the cancelation fut ure returned by \cd{cancell()} to complete before proceeding. | 3583 %When a stream is canceled, the implementation must wait for the cancelation fut ure returned by \cd{cancell()} to complete before proceeding. |
3565 | 3584 |
3566 \LMHash{} | 3585 \LMHash{} |
3567 If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementin g the built-in class \code{Iterable} is associated with the invocation and immed iately returned. | 3586 If $f$ is marked \SYNC* (\ref{functions}), then a fresh instance $i$ implementin g the built-in class \code{Iterable} is associated with the invocation and immed iately returned. |
3568 | 3587 |
3569 | 3588 |
3570 \commentary{ | 3589 \commentary{ |
3571 A Dart implementation will need to provide a specific implementation of \code{It erable} that will be returned by \SYNC* methods. A typical strategy would be to produce an instance of a subclass of class \code{IterableBase} defined in \code{ dart:core}. The only method that needs to be added by the Dart implementation in that case is \code{iterator}. | 3590 A Dart implementation will need to provide a specific implementation of \code{It erable} that will be returned by \SYNC* methods. A typical strategy would be to produce an instance of a subclass of class \code{IterableBase} defined in \code{ dart:core}. The only method that needs to be added by the Dart implementation in that case is \code{iterator}. |
3572 } | 3591 } |
3573 | 3592 |
3574 \LMHash{} | 3593 \LMHash{} |
3575 The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contrac t. | 3594 The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contrac t. |
3576 | 3595 |
3577 \commentary { | 3596 \commentary { |
3578 The contract explicitly mentions a number of situations where certain iterables could be more efficient than normal. For example, by precomputing their length. Normal iterables must iterate over their elements to determine their length. Thi s is certainly true in the case of a synchronous generator, where each element i s computed by a function. It would not be acceptable to pre-compute the results of the generator and cache them, for example. | 3597 The contract explicitly mentions a number of situations where certain iterables could be more efficient than normal. For example, by precomputing their length. Normal iterables must iterate over their elements to determine their length. Thi s is certainly true in the case of a synchronous generator, where each element i s computed by a function. It would not be acceptable to pre-compute the results of the generator and cache them, for example. |
3579 } | 3598 } |
3580 | 3599 |
3581 \LMHash{} | 3600 \LMHash{} |
3582 When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin . When $f$ terminates, $j$ is positioned after its last element, so that its cur rent value is \NULL{} and the current call to \code{moveNext()} on $j$ returns f alse, as will all further calls. | 3601 When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin . When $f$ completes (\ref{completion}, |
Kevin Millikin (Google)
2016/10/13 12:18:38
the body of f
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Done.
| |
3602 \begin{itemize} | |
3603 \item If $f$ {\em completes normally}, $j$ is positioned after its last element, so that its current value is \NULL{} and the current call to \code{moveNext()} on $j$ returns false, as will all further calls. | |
Kevin Millikin (Google)
2016/10/13 12:18:37
the body of f
Lasse Reichstein Nielsen
2016/10/17 10:08:24
Done.
| |
3604 \item If $f$ {\em throws} exception $e$ and stack trace $t$ then the current val ue is \NULL{} and the current call to \code{moveNext()} throws $e$ and $t$ as we ll. Further calls must return false. | |
Kevin Millikin (Google)
2016/10/13 12:18:38
the body of f
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Done.
| |
3605 \end{itemize} | |
3583 | 3606 |
3584 Each iterator starts a separate computation. If the \SYNC* function is impure, t he sequence of values yielded by each iterator may differ. | 3607 Each iterator starts a separate computation. If the \SYNC* function is impure, t he sequence of values yielded by each iterator may differ. |
3585 | 3608 |
3586 \commentary{ | 3609 \commentary{ |
3587 One can derive more than one iterator from a given iterable. Note that operati ons on the iterable itself can create distinct iterators. An example would be \c ode{length}. It is conceivable that different iterators might yield sequences o f different length. The same care needs to be taken when writing \SYNC* function s as when | 3610 One can derive more than one iterator from a given iterable. Note that operati ons on the iterable itself can create distinct iterators. An example would be \c ode{length}. It is conceivable that different iterators might yield sequences o f different length. The same care needs to be taken when writing \SYNC* function s as when |
3588 writing an \code{Iterator} class. In particular, it should handle multiple | 3611 writing an \code{Iterator} class. In particular, it should handle multiple |
3589 simultaneous iterators gracefully. If the iterator depends on external state | 3612 simultaneous iterators gracefully. If the iterator depends on external state |
3590 that might change, it should check that the state is still valid after every | 3613 that might change, it should check that the state is still valid after every |
3591 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). | 3614 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). |
3592 } | 3615 } |
3593 | 3616 |
3594 \LMHash{} | 3617 \LMHash{} |
3595 Each iterator runs with its own shallow copies of all local variables; in partic ular, each iterator has the same initial arguments, even if their bindings are m odified by the function. | 3618 Each iterator runs with its own shallow copies of all local variables; in partic ular, each iterator has the same initial arguments, even if their bindings are m odified by the function. |
3596 \commentary{ | 3619 \commentary{ |
3597 Two executions of an iterator interact only via state outside the function. | 3620 Two executions of an iterator interact only via state outside the function. |
3598 } | 3621 } |
3599 % The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. T he yielded value might differ from the expression in the yield. And it is a pote ntial memory leak as the cache is kept alive by any iterator. | 3622 % The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. T he yielded value might differ from the expression in the yield. And it is a pote ntial memory leak as the cache is kept alive by any iterator. |
3600 | 3623 |
3601 | 3624 |
3602 \LMHash{} | 3625 \LMHash{} |
3603 If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately. When $f$ terminates the current return val ue is returned to the caller. | 3626 If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately. |
3627 When $f$ completes (\ref{completion}) by returning a value, that value is return ed to the caller. | |
Kevin Millikin (Google)
2016/10/13 12:18:37
When ==> If
that value is returned to the caller
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Done.
| |
3628 If $f$ completes by returning without a value or by completing normally, \NULL{} is returned to the callee. | |
Kevin Millikin (Google)
2016/10/13 12:18:37
Definitely not callee :)
null is returned ==> the
Lasse Reichstein Nielsen
2016/10/17 10:08:23
-> the invocation evaluates to \code{null}.
| |
3629 If $f$ completes by {\em throwing}, the invoking call expression throws the same exception object and stack trace. | |
3604 | 3630 |
3605 | 3631 \commentary{ |
3606 \LMHash{} | 3632 A function body can never {\em abort} by {\em breaking} or {\em continuing} |
Kevin Millikin (Google)
2016/10/13 12:18:36
abort ==> complete
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Done.
| |
3607 Execution of $f$ terminates when the first of the following occurs: | 3633 because any \BREAK{} or \CONTINUE{} statement must occur inside a statement |
3608 \begin{itemize} | 3634 which will handle the \BREAK{} or \CONTINUE{}, |
3609 \item An exception is thrown and not caught within the current function activati on. | 3635 either by declaring the same label, if the \BREAK{} or \CONTINUE{} has a label, |
3610 \item A return statement (\ref{return}) immediately nested in the body of $f$ is executed and not intercepted in a \FINALLY{} (\ref{try}) clause. | 3636 or merely by being a loop or \SWITCH{} statement. |
3611 \item The last statement of the body completes execution. | 3637 This means that a function body can only abort by {\em throwing} or by {\em retu rning} a value, so a function call expression can always propagate the behavior of the called function's body. |
Kevin Millikin (Google)
2016/10/13 12:18:36
abort ==> complete
Lasse Reichstein Nielsen
2016/10/17 10:08:24
Done.
| |
3612 \end{itemize} | 3638 } |
3613 | |
3614 | |
3615 | |
3616 | 3639 |
3617 \subsubsection{ Actual Argument List Evaluation} | 3640 \subsubsection{ Actual Argument List Evaluation} |
3618 \LMLabel{actualArguments} | 3641 \LMLabel{actualArguments} |
3619 | 3642 |
3620 \LMHash{} | 3643 \LMHash{} |
3621 Function invocation involves evaluation of the list of actual arguments to the f unction and binding of the results to the function's formal parameters. | 3644 Function invocation involves evaluation of the list of actual arguments to the f unction and binding of the results to the function's formal parameters. |
3622 | 3645 |
3623 \begin{grammar} | 3646 \begin{grammar} |
3624 {\bf arguments:} | 3647 {\bf arguments:} |
3625 `(' (argumentList `,'?)? `)' | 3648 `(' (argumentList `,'?)? `)' |
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5005 \begin{grammar} | 5028 \begin{grammar} |
5006 {\bf awaitExpression:} | 5029 {\bf awaitExpression:} |
5007 \AWAIT{} unaryExpression | 5030 \AWAIT{} unaryExpression |
5008 \end{grammar} | 5031 \end{grammar} |
5009 | 5032 |
5010 \LMHash{} | 5033 \LMHash{} |
5011 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follo ws: | 5034 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follo ws: |
5012 First, the expression $e$ is evaluated. Next: | 5035 First, the expression $e$ is evaluated. Next: |
5013 | 5036 |
5014 \LMHash{} | 5037 \LMHash{} |
5015 If $e$ raises an exception $x$, then an instance $f$ of class \code{Future} is a llocated and later completed with $x$. Otherwise, if $e$ evaluates to an object $o$ that is not an instance of \code{Future}, then let $f$ be the result of call ing \code{Future.value()} with $o$ as its argument; otherwise let $f$ be the res ult of evaluating $e$. | 5038 % NOTICE: Removed the requirement that an error thrown by $e$ is caught in a |
Kevin Millikin (Google)
2016/10/13 12:18:36
Thank you!
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Acknowledged.
| |
5039 % future. There is no reason $var x = e; await x;$ and $await e$ should behave | |
5040 % differently, and no implementation actually implemented it. | |
5041 If $e$ evaluates to an object $o$ that is not an instance of \code{Future}, then let $f$ be the result of creating a new object using the constructor \code{Futu re.value()} with $o$ as its argument; otherwise let $f$ be the result of evaluat ing $e$. | |
Kevin Millikin (Google)
2016/10/13 12:18:36
The result of evaluating e is o (or maybe an excep
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Done.
| |
5016 | 5042 |
5017 \LMHash{} | 5043 \LMHash{} |
5018 Next, execution of the function $m$ immediately enclosing $a$ is suspended unti l after $f$ completes. The stream associated with the innermost enclosing asynch ronous for loop (\ref{asynchronousFor-in}), if any, is paused. At some time afte r $f$ is completed, control returns to the current invocation. The stream associ ated with the innermost enclosing asynchronous for loop (\ref{asynchronousFor-i n}), if any, is resumed. If $f$ has completed with an exception $x$, $a$ raises $x$. If $f$ completes with a value $v$, $a$ evaluates to $v$. | 5044 Next, the stream associated with the innermost enclosing asynchronous for loop ( \ref{asynchronousFor-in}), if any, is paused. Execution of the function $m$ imme diately enclosing $a$ is suspended until after $f$ completes. At some time after $f$ is completed, control returns to the current invocation. If $f$ has complet ed with an exception $x$ and stack trace $t$, $a$ {\em throws} $x$ and $t$. If $ f$ completes with a value $v$, $a$ evaluates to $v$. |
Kevin Millikin (Google)
2016/10/13 12:18:36
I would say that we're not really executing the fu
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Reworded.
| |
5019 | 5045 |
5020 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$. | 5046 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$. |
5021 | 5047 |
5022 \commentary{ | 5048 \commentary{ |
5023 It is a compile-time error if the function immediately enclosing $a$ is not declared asynchronous. However, this error is simply a syntax error, because in the context of a normal function, \AWAIT{} has no special meaning. | 5049 It is a compile-time error if the function immediately enclosing $a$ is not declared asynchronous. However, this error is simply a syntax error, because in the context of a normal function, \AWAIT{} has no special meaning. |
5050 % TODO(lrn): Update this, it's not actually correct, | |
5051 % the expression "await(expr)" is valid non-async syntax *and* a valid | |
5052 % async await expression. | |
5024 } | 5053 } |
5025 | 5054 |
5026 \rationale{ | 5055 \rationale{ |
5027 An await expression has no meaning in a synchronous function. If such a function were to suspend waiting for a future, it would no longer be synchronous. | 5056 An await expression has no meaning in a synchronous function. If such a function were to suspend waiting for a future, it would no longer be synchronous. |
5028 } | 5057 } |
5029 | 5058 |
5030 \commentary{ | 5059 \commentary{ |
5031 It is not a static warning if the type of $e$ is not a subtype of \code{Future}. Tools may choose to give a hint in such cases. | 5060 It is not a static warning if the type of $e$ is not a subtype of \code{Future}. Tools may choose to give a hint in such cases. |
5032 } | 5061 } |
5033 | 5062 |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5418 \LMHash{} | 5447 \LMHash{} |
5419 The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or d eferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the inte rface of the class of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise, if $v$ is \NULL{}, the cast expression evaluates to $v$. | 5448 The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or d eferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the inte rface of the class of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise, if $v$ is \NULL{}, the cast expression evaluates to $v$. |
5420 In all other cases, a \code{CastError} is thrown. | 5449 In all other cases, a \code{CastError} is thrown. |
5421 | 5450 |
5422 \LMHash{} | 5451 \LMHash{} |
5423 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. | 5452 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. |
5424 | 5453 |
5425 | 5454 |
5426 \section{Statements} | 5455 \section{Statements} |
5427 \LMLabel{statements} | 5456 \LMLabel{statements} |
5457 A {\em statement} is a fragment of Dart code that can be executed at runtime. St atements, unlike expressions, do not evaluate to a value, but are instead execut ed for their effect on the program state. | |
5458 Some statements can affect control flow, in particular \BREAK{}, \CONTINUE{}, \R ETURN{} and \THROW{} statements. | |
Kevin Millikin (Google)
2016/10/13 12:18:38
Throw is not a statement, but rethrow is. If you
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Reworded.
| |
5459 | |
5460 \LMLabel{completion} | |
5461 Execution of a statement can {\em complete} in two ways: either it {\em complete s normally} or it {\em aborts}. It can {\em abort} in one of four ways: Either i t {\em breaks} or it {\em continues} (either to a label or without a label), it {\em returns}, either with a value or without one, or it {\em throws} an excepti on object and an associated stack trace. | |
Kevin Millikin (Google)
2016/10/13 12:18:37
Instead of two possibilities, one of which is four
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Done.
| |
5462 | |
5463 In the description of statement execution, the default is that the execution | |
5464 {\em completes normally} unless otherwise stated. | |
5465 | |
5466 If the execution of a statement, $s$, is defined in terms of executing | |
5467 another statement, | |
5468 like the body of a loop or the branches of an \IF{} statement, | |
5469 and the execution of that other statement {\em aborts}, | |
5470 then, unless otherwise stated, the execution of $s$ stops | |
5471 at that point and aborts in the same way. | |
5472 | |
5473 If the execution of a statement is defined in terms of evaluating an expression, | |
5474 like the condition expression of an \IF{} statement or the value of a \RETURN{}, | |
5475 and the evaluation of that expression throws, | |
5476 then, unless otherwise stated, the execution of the statement stops | |
5477 at that point and throws the same exception object and stack trace. | |
5478 | |
5479 \LMHash{} | |
5428 | 5480 |
5429 \begin{grammar} | 5481 \begin{grammar} |
5430 {\bf statements:} | 5482 {\bf statements:} |
5431 statement* | 5483 statement* |
5432 . | 5484 . |
5433 | 5485 |
5434 | 5486 |
5435 {\bf statement:} | 5487 {\bf statement:} |
5436 label* nonLabelledStatement | 5488 label* nonLabelledStatement |
5437 . | 5489 . |
(...skipping 15 matching lines...) Expand all Loading... | |
5453 expressionStatement; | 5505 expressionStatement; |
5454 assertStatement; | 5506 assertStatement; |
5455 localFunctionDeclaration | 5507 localFunctionDeclaration |
5456 . | 5508 . |
5457 \end{grammar} | 5509 \end{grammar} |
5458 | 5510 |
5459 \subsection{Blocks} | 5511 \subsection{Blocks} |
5460 \LMLabel{blocks} | 5512 \LMLabel{blocks} |
5461 | 5513 |
5462 \LMHash{} | 5514 \LMHash{} |
5463 A {\em block statement} supports sequencing of code. | 5515 A {\em block statement} supports sequencing of code. |
5464 | 5516 |
5465 \LMHash{} | 5517 \LMHash{} |
5466 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: | 5518 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: |
5467 | 5519 |
5468 \LMHash{} | 5520 \LMHash{} |
5469 For $i \in 1 .. n, s_i$ is executed. | 5521 For $i \in 1 .. n, s_i$ is executed. |
5470 | 5522 |
5471 \LMHash{} | 5523 \LMHash{} |
5472 A block statement introduces a new scope, which is nested in the lexically enclo sing scope in which the block statement appears. | 5524 A block statement introduces a new scope, which is nested in the lexically enclo sing scope in which the block statement appears. |
5473 | 5525 |
5474 | 5526 \subsection{Expression Statements} |
5475 | 5527 \LMLabel{expressionStatements} |
5476 \subsection{Expression Statements} | |
5477 \LMLabel{expressionStatements} | |
5478 | 5528 |
5479 \LMHash{} | 5529 \LMHash{} |
5480 An {\em expression statement} consists of an expression other than a non-constan t map literal (\ref{maps}) that has no explicit type arguments. | 5530 An {\em expression statement} consists of an expression other than a non-constan t map literal (\ref{maps}) that has no explicit type arguments. |
5481 | 5531 |
5482 \rationale{ | 5532 \rationale{ |
5483 The restriction on maps is designed to resolve an ambiguity in the grammar, whe n a statement begins with \{. | 5533 The restriction on maps is designed to resolve an ambiguity in the grammar, whe n a statement begins with \{. |
5484 } | 5534 } |
5485 | 5535 |
5486 \begin{grammar} | 5536 \begin{grammar} |
5487 {\bf expressionStatement:} | 5537 {\bf expressionStatement:} |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5594 % elaborate on function identity and equality, runtime type. Likewsie in functio n expressions (closures) and declarations | 5644 % elaborate on function identity and equality, runtime type. Likewsie in functio n expressions (closures) and declarations |
5595 | 5645 |
5596 \subsection{If} | 5646 \subsection{If} |
5597 \LMLabel{if} | 5647 \LMLabel{if} |
5598 | 5648 |
5599 \LMHash{} | 5649 \LMHash{} |
5600 The {\em if statement} allows for conditional execution of statements. | 5650 The {\em if statement} allows for conditional execution of statements. |
5601 | 5651 |
5602 \begin{grammar} | 5652 \begin{grammar} |
5603 {\bf ifStatement:} | 5653 {\bf ifStatement:} |
5604 \IF{} `(' expression `)' statement ( \ELSE{} statement)? % we could allow top level expression | 5654 \IF{} `(' expression `)' statement ( \ELSE{} statement)? |
5605 . | 5655 . |
5606 \end{grammar} | 5656 \end{grammar} |
5607 | 5657 |
5608 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{ \ELSE{} } $s_2$ proceeds as follows: | 5658 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{ \ELSE{} } $s_2$ proceeds as follows: |
5609 | 5659 |
5610 \LMHash{} | 5660 \LMHash{} |
5611 First, the expression $b$ is evaluated to an object $o$. Then, $o$ is subjecte d to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $ r$ is \TRUE{}, then the statement $\{s_1\}$ is executed, otherwise statement $\{ s_2\}$ is executed. | 5661 First, the expression $b$ is evaluated to an object $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion}), producing an object $r$. If $r $ is \TRUE{}, then the statement $\{s_1\}$ is executed, otherwise statement $\{s _2\}$ is executed. |
5612 | |
5613 | 5662 |
5614 \commentary { | 5663 \commentary { |
5615 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv alent to | 5664 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv alent to |
5616 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ | 5665 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ |
5617 } | 5666 } |
5618 | 5667 |
5619 \rationale { | 5668 \rationale { |
5620 The reason for this equivalence is to catch errors such as | 5669 The reason for this equivalence is to catch errors such as |
5621 } | 5670 } |
5622 \begin{dartCode} | 5671 \begin{dartCode} |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5684 \LMHash{} | 5733 \LMHash{} |
5685 If $c$ is empty then let $c^\prime$ be \TRUE{} otherwise let $c^\prime$ be $c$. | 5734 If $c$ is empty then let $c^\prime$ be \TRUE{} otherwise let $c^\prime$ be $c$. |
5686 | 5735 |
5687 \LMHash{} | 5736 \LMHash{} |
5688 First the variable declaration statement \VAR{} $v = e_0$ is executed. Then: | 5737 First the variable declaration statement \VAR{} $v = e_0$ is executed. Then: |
5689 \begin{enumerate} | 5738 \begin{enumerate} |
5690 \item | 5739 \item |
5691 \label{beginFor} | 5740 \label{beginFor} |
5692 If this is the first iteration of the for loop, let $v^\prime$ be $v$. Otherwise , let $v^\prime$ be the variable $v^{\prime\prime}$ created in the previous exe cution of step \ref{allocateFreshVar}. | 5741 If this is the first iteration of the for loop, let $v^\prime$ be $v$. Otherwise , let $v^\prime$ be the variable $v^{\prime\prime}$ created in the previous exe cution of step \ref{allocateFreshVar}. |
5693 \item | 5742 \item |
5694 The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion (\ref{booleans}). If the result is \FALSE{}, the for loop completes. Otherwise, execution continues at step | 5743 The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion (\ref{booleans}). If the result is \FALSE{}, the for loop completes. Otherwise, execution continues at step |
Kevin Millikin (Google)
2016/10/13 12:18:38
completes ==> completes normally
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Done.
| |
5695 \ref{beginIteration}. | 5744 \ref{beginIteration}. |
5696 \item | 5745 \item |
5697 \label{beginIteration} | 5746 \label{beginIteration} |
5698 The statement $[v^\prime/v]\{s\}$ is executed. | 5747 The statement $[v^\prime/v]\{s\}$ is executed. |
5699 \item | 5748 |
5749 If this execution {\em continues} without a label, | |
5750 or with a label that this \FOR{} statement is labeled with (\ref{labels}), | |
5751 then the statement is treated as if it had completed normally. | |
5752 If it aborts in any other way, | |
5753 execution of the for loop stops and aborts in the same way. | |
5754 | |
5700 \label{allocateFreshVar} | 5755 \label{allocateFreshVar} |
5701 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the value of $v^\prime$. | 5756 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the value of $v^\prime$. |
5702 \item | 5757 \item |
5703 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at step | 5758 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at step |
5704 \ref{beginFor}. | 5759 \ref{beginFor}. |
5705 \end{enumerate} | 5760 \end{enumerate} |
5706 | 5761 |
5707 \rationale{ | 5762 \rationale{ |
5708 The definition above is intended to prevent the common error where users create a closure inside a for loop, intending to close over the current binding of the loop variable, and find (usually after a painful process of debugging and learni ng) that all the created closures have captured the same value - the one current in the last iteration executed. | 5763 The definition above is intended to prevent the common error where users create a closure inside a for loop, intending to close over the current binding of the loop variable, and find (usually after a painful process of debugging and learni ng) that all the created closures have captured the same value - the one current in the last iteration executed. |
5709 | 5764 |
(...skipping 23 matching lines...) Expand all Loading... | |
5733 | 5788 |
5734 \begin{dartCode} | 5789 \begin{dartCode} |
5735 var n0 = $e$.iterator; | 5790 var n0 = $e$.iterator; |
5736 \WHILE{} (n0.moveNext()) \{ | 5791 \WHILE{} (n0.moveNext()) \{ |
5737 $finalConstVarOrType?$ id = n0.current; | 5792 $finalConstVarOrType?$ id = n0.current; |
5738 $s$ | 5793 $s$ |
5739 \} | 5794 \} |
5740 \end{dartCode} | 5795 \end{dartCode} |
5741 where \code{n0} is an identifier that does not occur anywhere in the program, ex cept that for purposes of static typechecking, it is checked under the assumptio n that $n0$ is declared to be of type $T$, where $T$ is the static type of $e.it erator$. | 5796 where \code{n0} is an identifier that does not occur anywhere in the program, ex cept that for purposes of static typechecking, it is checked under the assumptio n that $n0$ is declared to be of type $T$, where $T$ is the static type of $e.it erator$. |
5742 | 5797 |
5743 | |
5744 | |
5745 \subsubsection{Asynchronous For-in} | 5798 \subsubsection{Asynchronous For-in} |
5746 \LMLabel{asynchronousFor-in} | 5799 \LMLabel{asynchronousFor-in} |
5747 | 5800 |
5748 \LMHash{} | 5801 \LMHash{} |
5749 A for-in statement may be asynchronous. The asynchronous form is designed to ite rate over streams. An asynchronous for loop is distinguished by the keyword \AWA IT{} immediately preceding the keyword \FOR. | 5802 A for-in statement may be asynchronous. The asynchronous form is designed to ite rate over streams. An asynchronous for loop is distinguished by the keyword \AWA IT{} immediately preceding the keyword \FOR. |
5750 | 5803 |
5751 \LMHash{} | 5804 \LMHash{} |
5752 Execution of a for-in statement of the form \code{\AWAIT{} \FOR{} (finalConstVa rOrType? id \IN{} $e$) $s$} proceeds as follows: | 5805 Execution of a for-in statement, $f$, of the form \code{\AWAIT{} \FOR{} (finalCo nstVarOrType? id \IN{} $e$) $s$} proceeds as follows: |
eernst
2016/10/19 13:37:04
We do have a couple of occurrences of `id` as a me
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Done.
| |
5753 | 5806 |
5754 \LMHash{} | 5807 \LMHash{} |
5755 The expression $e$ is evaluated to an object $o$. It is a dynamic error if $o$ i s not an instance of a class that implements \code{Stream}. Otherwise, the expre ssion \code{\AWAIT{} $v_f$} (\ref{awaitExpressions}) is evaluated, where $v_f$ is a fresh variable whose value is a fresh instance (\ref{generativeConstructors }) $f$ implementing the built-in class \code{Future}. | 5808 The expression $e$ is evaluated to an object $o$. |
5809 It is a dynamic error if $o$ is not an instance of a class that implements \code {Stream}. | |
5756 | 5810 |
5757 \LMHash{} | 5811 \LMHash{} |
5758 The stream $o$ is listened to, and on each data event in $o$ the statement $s$ is executed with \code{id} bound to the value of the current element of the stre am. If $s$ raises an exception, or if $o$ raises an exception, then $f$ is compl eted with that exception. Otherwise, when all events in the stream $o$ have been processed, $f$ is completed with \NULL{} (\ref{null}). | 5812 The stream associated with the innermost enclosing asynchronous for loop, if any , is paused. |
5813 The stream $o$ is listened to, producing a stream subscription $u$, | |
eernst
2016/10/19 13:37:04
Yes, thank you! The spec mentions stream subscript
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Acknowledged.
| |
5814 and execution of the asynchronous for-in loop is suspended | |
5815 until a stream event is available. | |
5816 This allows other asynchronous events to execute while this loop is waiting for stream events. | |
eernst
2016/10/19 13:37:05
This sentence should not be normative, but it migh
Lasse Reichstein Nielsen
2016/10/19 14:34:32
I'm not sure where we define "suspend", so I thoug
| |
5817 | |
5818 Pausing an asynchronous for loop means pausing the associated stream subscriptio n. | |
5819 A stream subscription is paused by calling its \code{pause} method. | |
5820 \commentary{ | |
5821 The \code{pause} call can throw, although that should never happen for a correct ly implemented stream. | |
5822 } | |
5823 If the subscription is already paused, the \code{pause} call may be omitted. | |
eernst
2016/10/19 13:37:05
I think it gets too difficult to distinguish comme
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Done.
| |
5759 | 5824 |
5760 \LMHash{} | 5825 \LMHash{} |
5761 Let $u$ be the stream associated with the immediately enclosing asynchronous for loop or generator function (\ref{functions}), if any. If another event $e_u$ of $u$ occurs before execution of $s$ is complete, handling of $e_u$ must wait unt il $s$ is complete. | 5826 For each {\em data event} from $u$, |
5827 the statement $s$ is executed with \code{id} bound to the value of the current d ata event. | |
eernst
2016/10/19 13:37:05
\code{id} --> $id$
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Done.
| |
5762 | 5828 |
5763 \rationale{ | 5829 \LMHash{} |
5764 The future $f$ and the corresponding \AWAIT{} expression ensure that execution s uspends as an asynchronous for loop begins and resumes after the \FOR{} statemen t when it ends. They also ensure that the stream of any enclosing asynchronous \ FOR{} loop is paused for the duration of this loop. | 5830 If another event $e_u$ of $u$ occurs before execution of $s$ is complete, handli ng of $e_u$ must wait until $s$ is complete. |
eernst
2016/10/19 13:37:04
This could be commentary, but for normative text w
Lasse Reichstein Nielsen
2016/10/31 16:54:43
We can pause the source stream. That will definite
| |
5831 | |
5832 \LMHash{} | |
5833 If execution of $s$ {\em continues} with no label, or with a label that prefixes the asynchronous for statement (\ref{labels}), then the execution of $s$ is tre ated as if it had completed normally. | |
eernst
2016/10/19 13:37:05
I still think that it's messy to add `{\em ..}` in
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Removing all the {\em's}.
| |
5834 | |
5835 If execution of $s$ {\em aborts} in any other way, the subscription $u$ is cance led by evaluating \code{\AWAIT{} v.cancel()} where $v$ is a fresh variable refer encing the stream subscription $u$. | |
5836 If that evaluation throws, | |
5837 execution of $f$ throws the same exception and stack trace. | |
5838 Otherwise execution of $f$ aborts in the same way as the execution of $s$. | |
5839 % Notice: The previous specification was unclear about what happened when | |
5840 % a subscripton is canceled. This text is explicit, and existing | |
5841 % implementations may not properly await the cancel call. | |
5842 | |
5843 Otherwise the execution of $f$ is suspended again, waiting for the next stream s ubscription event, and $u$ is resumed if it has been paused. | |
5844 If $u$ has been paused more than once, the \code{resume} method is called | |
5845 until $u$ is no longer paused. | |
eernst
2016/10/19 13:37:05
Couldn't we mandate the interpretation that '$u$ i
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Let's do that.
| |
5846 \commentary{ | |
5847 The \code{resume} call can throw, in which case it aborts the asynchronous for | |
5848 loop. That should never happen for a correctly implemented stream. | |
5765 } | 5849 } |
5766 | 5850 |
5767 \LMHash{} | 5851 \LMHash{} |
5852 On the first {\em error event} from $u$, | |
5853 with error object $e$ and stack trace $st$, | |
5854 the subscription $u$ is canceled by evaluating \code{\AWAIT{} v.cancel()} | |
5855 where $v$ is a fresh variable referencing the stream subscription $u$. | |
5856 If that evaluation throws, | |
5857 execution of $f$ throws the same exception object and stack trace. | |
5858 Otherwise execution of $f$ throws with $e$ as exception object and $st$ as stack trace. | |
5859 | |
5860 \LMHash{} | |
5861 When $u$ is done, execution of $f$ completes normally. | |
5862 | |
5863 \LMHash{} | |
5768 It is a compile-time error if an asynchronous for-in statement appears inside a synchronous function (\ref{functions}). It is a compile-time error if a traditio nal for loop (\ref{forLoop}) is prefixed by the \AWAIT{} keyword. | 5864 It is a compile-time error if an asynchronous for-in statement appears inside a synchronous function (\ref{functions}). It is a compile-time error if a traditio nal for loop (\ref{forLoop}) is prefixed by the \AWAIT{} keyword. |
5769 | 5865 |
5770 \rationale{An asynchronous loop would make no sense within a synchronous functio n, for the same reasons that an await expression makes no sense in a synchronous function.} | 5866 \rationale{An asynchronous loop would make no sense within a synchronous functio n, for the same reasons that an await expression makes no sense in a synchronous function.} |
5771 | 5867 |
5772 | 5868 |
5773 \subsection{While} | 5869 \subsection{While} |
5774 \LMLabel{while} | 5870 \LMLabel{while} |
5775 | 5871 |
5776 \LMHash{} | 5872 \LMHash{} |
5777 The while statement supports conditional iteration, where the condition is evalu ated prior to the loop. | 5873 The while statement supports conditional iteration, where the condition is evalu ated prior to the loop. |
5778 | 5874 |
5779 \begin{grammar} | 5875 \begin{grammar} |
5780 {\bf whileStatement:} | 5876 {\bf whileStatement:} |
5781 \WHILE{} `(' expression `)' statement % could do top level here, and in f or | 5877 \WHILE{} `(' expression `)' statement % could do top level here, and in f or |
5782 . | 5878 . |
5783 \end{grammar} | 5879 \end{grammar} |
5784 | 5880 |
5785 \LMHash{} | 5881 \LMHash{} |
5786 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds as follows: | 5882 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds a s follows: |
5787 | 5883 |
5788 \LMHash{} | 5884 \LMHash{} |
5789 The expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to boo lean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \ TRUE{}, then the statement $\{s\}$ is executed and then the while statement is r e-executed recursively. If $r$ is \FALSE{}, execution of the while statement is complete. | 5885 The expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to bool ean conversion (\ref{booleanConversion}), producing an object $r$. |
5886 | |
5887 If $r$ is \TRUE{}, then the statement $\{s\}$ is executed. | |
5888 If that execution completes normally or it {\em continues} with no label or with a label that prefixes the \WHILE{} statement (\ref{labels}), then the while sta tement is re-executed. | |
Kevin Millikin (Google)
2016/10/13 12:18:37
For 'for' we have the language "a label that this
Lasse Reichstein Nielsen
2016/10/17 10:08:23
It seems "prefixes" is the wording used in most ot
eernst
2016/10/19 13:37:05
New style: 'completes normally or it continues wit
| |
5889 | |
5890 If $r$ is \FALSE{}, then execution of the while statement completes normally. | |
eernst
2016/10/19 13:37:04
+` (\ref{completion})`
| |
5790 | 5891 |
5791 \LMHash{} | 5892 \LMHash{} |
5792 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. | 5893 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. |
5793 | 5894 |
5794 | 5895 |
5795 \subsection{Do} | 5896 \subsection{Do} |
5796 \LMLabel{do} | 5897 \LMLabel{do} |
5797 | 5898 |
5798 \LMHash{} | 5899 \LMHash{} |
5799 The do statement supports conditional iteration, where the condition is evaluate d after the loop. | 5900 The do statement supports conditional iteration, where the condition is evaluate d after the loop. |
5800 | 5901 |
5801 \begin{grammar} | 5902 \begin{grammar} |
5802 {\bf doStatement:} | 5903 {\bf doStatement:} |
5803 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t op level here | 5904 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t op level here |
5804 . | 5905 . |
5805 \end{grammar} | 5906 \end{grammar} |
5806 | 5907 |
5807 | 5908 |
5808 \LMHash{} | 5909 \LMHash{} |
5809 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed s as follows: | 5910 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed s as follows: |
5810 | 5911 |
5811 \LMHash{} | 5912 \LMHash{} |
5812 The statement $\{s\}$ is executed. Then, the expression $e$ is evaluated to an o bject $o$. Then, $o$ is subjected to boolean conversion (\ref{booleanConversion }), producing an object $r$. If $r$ is \FALSE{}, execution of the do statement i s complete. If $r$ is \TRUE{}, then the do statement is re-executed recursively. | 5913 The statement $\{s\}$ is executed. |
5914 If that execution {\em continues} with no label, or with a label that prefixes t he do statement (\ref{labels}), then the execution of $s$ is treated as if it ha d completed normally. | |
eernst
2016/10/19 13:37:05
The usual stuff: `If that execution continues with
| |
5915 | |
5916 \LMHash{} | |
5917 Then, the expression $e$ is evaluated to an object $o$. Then, $o$ is subjected t o boolean conversion (\ref{booleanConversion}), producing an object $r$. If $r$ is \FALSE{}, execution of the do statement completes normally. | |
eernst
2016/10/19 13:37:05
+` (\ref{completion})`
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Do we need this reference when we had one in the p
| |
5918 If $r$ is \TRUE{}, then the do statement is re-executed. | |
5813 | 5919 |
5814 \LMHash{} | 5920 \LMHash{} |
5815 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. | 5921 It is a static type warning if the static type of $e$ may not be assigned to \co de{bool}. |
5816 | 5922 |
5817 \subsection{Switch} | 5923 \subsection{Switch} |
5818 \LMLabel{switch} | 5924 \LMLabel{switch} |
5819 | 5925 |
5820 \LMHash{} | 5926 \LMHash{} |
5821 The {\em switch statement} supports dispatching control among a large number of cases. | 5927 The {\em switch statement} supports dispatching control among a large number of cases. |
5822 | 5928 |
5823 \begin{grammar} | 5929 \begin{grammar} |
5824 {\bf switchStatement:} | 5930 {\bf switchStatement:} |
5825 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do top level here and in cases | 5931 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do top level here and in cases |
5826 . | 5932 . |
5827 | 5933 |
5828 | 5934 |
5829 {\bf switchCase:} | 5935 {\bf switchCase:} |
5830 label* \CASE{} expression `{\escapegrammar :}' statements | 5936 label* \CASE{} expression `{\escapegrammar :}' statements |
5831 . | 5937 . |
5832 | 5938 |
5833 {\bf defaultCase:} | 5939 {\bf defaultCase:} |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5897 \SWITCH{} ($e$) \{ | 6003 \SWITCH{} ($e$) \{ |
5898 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 6004 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5899 $\ldots$ | 6005 $\ldots$ |
5900 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 6006 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5901 \} | 6007 \} |
5902 \end{dartCode} | 6008 \end{dartCode} |
5903 | 6009 |
5904 proceeds as follows: | 6010 proceeds as follows: |
5905 | 6011 |
5906 \LMHash{} | 6012 \LMHash{} |
5907 The statement \code{\VAR{} id = $e$;} is evaluated, where \code{id} is a variabl e whose name is distinct from any other variable in the program. In checked mode , it is a run time error if the value of $e$ is not an instance of the same clas s as the constants $e_1 \ldots e_n$. | 6013 The statement \code{\VAR{} id = $e$;} is evaluated, where \code{id} is a variabl e whose name is distinct from any other variable in the program. In checked mode , it is a run time error if the value of $e$ is not an instance of the same clas s as the constants $e_1 \ldots e_n$. |
Kevin Millikin (Google)
2016/10/13 12:18:36
Since you've explicitly defined matching against a
Lasse Reichstein Nielsen
2016/10/17 10:08:24
We actually do use `id` below in the expression $e
| |
5908 | 6014 |
5909 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do es not matter.} | 6015 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do es not matter.} |
5910 | 6016 |
5911 \LMHash{} | 6017 \LMHash{} |
5912 Next, the case clause \CASE{} $e_{1}: s_{1}$ is executed if it exists. If \CASE{ } $e_{1}: s_{1}$ does not exist, then if there is a \DEFAULT{} clause it is exe cuted by executing $s_{n+1}$. | 6018 Next, the case clause \CASE{} $e_{1}: s_{1}$ is matched against {\code id} if it exists. If \CASE{} $e_{1}: s_{1}$ does not exist, then if there is a \DEFAULT{} clause, its statements, if any, are executed (\ref{case-execute}). |
Kevin Millikin (Google)
2016/10/13 12:18:37
It sounds like id might not exist. I would say so
eernst
2016/10/19 13:37:04
I suggested switching the order, which would handl
| |
5913 | 6019 |
5914 \LMHash{} | 6020 \LMHash{} |
5915 A case clause introduces a new scope, nested in the lexically surrounding scope. The scope of a case clause ends immediately after the case clause's statement l ist. | 6021 A case clause introduces a new scope, nested in the lexically surrounding scope. The scope of a case clause ends immediately after the case clause's statement l ist. |
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Removed
| |
5916 | 6022 |
5917 \LMHash{} | 6023 \LMHash{} |
5918 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 6024 Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5919 | 6025 |
5920 \begin{dartCode} | 6026 \begin{dartCode} |
5921 \SWITCH{} ($e$) \{ | 6027 \SWITCH{} ($e$) \{ |
5922 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 6028 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5923 $\ldots$ | 6029 $\ldots$ |
5924 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 6030 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5925 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ | 6031 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5926 \} | 6032 \} |
5927 \end{dartCode} | 6033 \end{dartCode} |
5928 | 6034 |
5929 proceeds as follows: | 6035 against a value {\code id} proceeds as follows: |
5930 | 6036 |
5931 \LMHash{} | 6037 \LMHash{} |
5932 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. | 6038 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. |
5933 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut ed if it exists. If \CASE{} $e_{k+1}: s_{k+1}$ does not exist, then the \DEFAUL T{} clause is executed by executing $s_{n+1}$. | 6039 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched against {\code id} if it exists. If \CASE{} $e_{k+1}: s_{k+1}$ does not exist, t hen the \DEFAULT{} clause's statements are executed (\ref{case-execute}). |
Kevin Millikin (Google)
2016/10/13 12:18:36
Again, it sounds like id might not exist.
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Done.
eernst
2016/10/19 13:37:05
I'd suggest a similar rewrite as the previous one
Lasse Reichstein Nielsen
2016/10/31 16:54:43
Rewritten again to not say "if such a thing exists
| |
5934 If $v$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h $ is non-empty. If no such $h$ exists, let $h = n + 1$. The sequence of stateme nts $s_h$ is then executed. | 6040 If $v$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h$ is non-empty. If no such $h$ exists, let $h = n + 1$. The statements $s_h$ are t hen executed (\ref{case-execute}). |
5935 If execution reaches the point after $s_h$ then a runtime error occurs, unless $h = n+1$. | |
5936 | 6041 |
5937 \LMHash{} | 6042 \LMHash{} |
5938 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 6043 Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5939 | 6044 |
5940 \begin{dartCode} | 6045 \begin{dartCode} |
5941 \SWITCH{} ($e$) \{ | 6046 \SWITCH{} ($e$) \{ |
5942 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 6047 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5943 $\ldots$ | 6048 $\ldots$ |
5944 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 6049 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5945 \} | 6050 \} |
5946 \end{dartCode} | 6051 \end{dartCode} |
5947 | 6052 |
6053 against a value {\code id} proceeds as follows: | |
6054 | |
6055 \LMHash{} | |
6056 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. | |
Kevin Millikin (Google)
2016/10/13 12:18:37
Note that there may be zero cases, so you need the
Lasse Reichstein Nielsen
2016/10/17 10:08:22
I don't think that is necessary, it's handled at t
| |
6057 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matche d against {\code id} if it exists. | |
6058 If $v$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_h$ is non-empty. The sequence of statements $s_h$ is executed if it exists (\ref{c ase-execute}). | |
6059 | |
6060 \LMHash{} | |
6061 \subsection{ Executing the statements of a switch case} | |
Kevin Millikin (Google)
2016/10/13 12:18:38
Should be a subsubsection of switch I think.
Lasse Reichstein Nielsen
2016/10/17 10:08:24
Absolutely, and should have a more consistent name
| |
6062 \LMLabel{case-execute} | |
6063 Execution of the statements $s_h$ of a switch statement | |
6064 | |
6065 \begin{dartCode} | |
6066 \SWITCH{} ($e$) \{ | |
6067 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | |
6068 $\ldots$ | |
6069 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | |
6070 \} | |
6071 \end{dartCode} | |
6072 | |
6073 or a switch statement | |
6074 | |
6075 \begin{dartCode} | |
6076 \SWITCH{} ($e$) \{ | |
6077 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | |
6078 $\ldots$ | |
6079 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | |
6080 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ | |
6081 \} | |
6082 \end{dartCode} | |
6083 | |
5948 proceeds as follows: | 6084 proceeds as follows: |
5949 | 6085 |
5950 \LMHash{} | 6086 \LMHash{} |
5951 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su bjected to boolean conversion yielding a value $v$. | 6087 Execute $\{s_h\}$. |
Kevin Millikin (Google)
2016/10/13 12:18:36
Note that the language about how a case clause int
Lasse Reichstein Nielsen
2016/10/17 10:08:24
Done.
| |
5952 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut ed if it exists. | 6088 If this execution completes normally, and if $s_h$ is not the statements of the last case of the switch ($h = n$ if there is no \DEFAULT{} clause, $h = n+1$ if there is a \DEFAULT{} clause), then the execution of the switch case aborts by t hrowing a runtime error. Otherwise $s_h$ are the last statements of the switch c ase, and execution of the switch case completes normally. |
Kevin Millikin (Google)
2016/10/13 12:18:38
aborts ==> completex
Lasse Reichstein Nielsen
2016/10/17 10:08:23
Done.
| |
5953 If $v$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_ h$ is non-empty. The sequence of statements $s_h$ is executed if it exists. | |
5954 If execution reaches the point after $s_h$ then a runtime error occurs, unless $h = n$. | |
5955 | |
5956 | 6089 |
5957 \commentary{ | 6090 \commentary{ |
5958 In other words, there is no implicit fall-through between non-empty cases. The l ast case in a switch (default or otherwise) can `fall-through' to the end of the statement. | 6091 In other words, there is no implicit fall-through between non-empty cases. The l ast case in a switch (default or otherwise) can `fall-through' to the end of the statement. |
5959 } | 6092 } |
5960 | 6093 |
6094 If execution of $\{s_h\}$ aborts by {\em breaking} with no label, or with a labe l that prefixes the switch statement, then the execution of the switch statement completes normally. | |
6095 | |
6096 If execution of $\{s_h\}$ aborts with a continue with a label, and the label is $label_{ij}$, where $1 \le i \le n+1$ if the \SWITCH{} statement has a \DEFAULT{ }, or $1 \le i \le n$ if there is no \DEFAULT{}, and where $1 \le j \le j_{i}$, then | |
6097 execution of the switch statement continues with the case labeled by that label. | |
6098 let $h$ be the smallest number such that $h \ge i$ and $s_h$ is non-empty. If no such $h$ exists, and let $h = n + 1$ if the \SWITCH{} statement has a \DEFAULT{ }, otherwise let $h = n$. | |
6099 The statements $s_h$ are then executed (\ref{case-execute}). | |
6100 | |
6101 If execution of $\{s_h\}$ aborts in any other way, execution of the \SWITCH{} st atement aborts in the same way. | |
6102 | |
5961 \LMHash{} | 6103 \LMHash{} |
5962 It is a static warning if the type of $e$ may not be assigned to the type of $e_ k$. It is a static warning if the last statement of the statement sequence $s_k$ is not a \BREAK{}, \CONTINUE{}, \RETURN{} or \THROW{} statement. | 6104 It is a static warning if the type of $e$ may not be assigned to the type of $e_ k$. It is a static warning if the last statement of the statement sequence $s_k$ is not a \BREAK{}, \CONTINUE{}, \RETURN{} or \THROW{} statement. |
Kevin Millikin (Google)
2016/10/13 12:18:36
This paragraph and the rest of this section is out
Lasse Reichstein Nielsen
2016/10/17 10:08:22
Moved it to before the subsection.
| |
5963 | 6105 |
5964 \rationale{ | 6106 \rationale{ |
5965 The behavior of switch cases intentionally differs from the C tradition. Implic it fall through is a known cause of programming errors and therefore disallowed. Why not simply break the flow implicitly at the end of every case, rather than requiring explicit code to do so? This would indeed be cleaner. It would also be cleaner to insist that each case have a single (possibly compound) statement . We have chosen not to do so in order to facilitate porting of switch statemen ts from other languages. Implicitly breaking the control flow at the end of a c ase would silently alter the meaning of ported code that relied on fall-through, potentially forcing the programmer to deal with subtle bugs. Our design ensures that the difference is immediately brought to the coder's attention. The progr ammer will be notified at compile-time if they forget to end a case with a state ment that terminates the straight-line control flow. We could make this warning a compile-time error, but refrain from doing so because do not wish to force the programmer to deal with this issue immediately while porting code. If develope rs ignore the warning and run their code, a run time error will prevent the prog ram from misbehaving in hard-to-debug ways (at least with respect to this issue) . | 6107 The behavior of switch cases intentionally differs from the C tradition. Implic it fall through is a known cause of programming errors and therefore disallowed. Why not simply break the flow implicitly at the end of every case, rather than requiring explicit code to do so? This would indeed be cleaner. It would also be cleaner to insist that each case have a single (possibly compound) statement . We have chosen not to do so in order to facilitate porting of switch statemen ts from other languages. Implicitly breaking the control flow at the end of a c ase would silently alter the meaning of ported code that relied on fall-through, potentially forcing the programmer to deal with subtle bugs. Our design ensures that the difference is immediately brought to the coder's attention. The progr ammer will be notified at compile-time if they forget to end a case with a state ment that terminates the straight-line control flow. We could make this warning a compile-time error, but refrain from doing so because do not wish to force the programmer to deal with this issue immediately while porting code. If develope rs ignore the warning and run their code, a run time error will prevent the prog ram from misbehaving in hard-to-debug ways (at least with respect to this issue) . |
5966 | 6108 |
5967 The sophistication of the analysis of fall-through is another issue. For now, we have opted for a very straightforward syntactic requirement. There are obviousl y situations where code does not fall through, and yet does not conform to these simple rules, e.g.: | 6109 The sophistication of the analysis of fall-through is another issue. For now, we have opted for a very straightforward syntactic requirement. There are obviousl y situations where code does not fall through, and yet does not conform to these simple rules, e.g.: |
5968 } | 6110 } |
5969 | 6111 |
5970 \begin{dartCode} | 6112 \begin{dartCode} |
5971 \SWITCH{} (x) \{ | 6113 \SWITCH{} (x) \{ |
5972 \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN{};\} \FINALLY{} \{ $\ldots$ \RETURN{};\} | 6114 \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN{};\} \FINALLY{} \{ $\ldots$ \RETURN{};\} |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6007 Execution of a \code{\RETHROW{}} statement proceeds as follows: | 6149 Execution of a \code{\RETHROW{}} statement proceeds as follows: |
6008 | 6150 |
6009 \LMHash{} | 6151 \LMHash{} |
6010 Let $f$ be the immediately enclosing function, and let \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} be the immediately enclosing catch clause (\ref{try}). | 6152 Let $f$ be the immediately enclosing function, and let \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} be the immediately enclosing catch clause (\ref{try}). |
6011 | 6153 |
6012 \rationale{ | 6154 \rationale{ |
6013 A \RETHROW{} statement always appears inside a \CATCH{} clause, and any \CATCH{} clause is semantically equivalent to some \CATCH{} clause of the form \code{\ON {} $T$ \CATCH{} (p1, p2)}. So we can assume that the \RETHROW{} is enclosed in a \CATCH{} clause of that form. | 6155 A \RETHROW{} statement always appears inside a \CATCH{} clause, and any \CATCH{} clause is semantically equivalent to some \CATCH{} clause of the form \code{\ON {} $T$ \CATCH{} (p1, p2)}. So we can assume that the \RETHROW{} is enclosed in a \CATCH{} clause of that form. |
6014 } | 6156 } |
6015 | 6157 |
6016 \LMHash{} | 6158 \LMHash{} |
6017 The current exception (\ref{throw}) is set to $p_1$, the current return value (\ ref{return}) becomes undefined, and the active stack trace (\ref{try}) is set to $p_2$. | 6159 The \RETHROW{} statement aborts by {\em throwing} with $p_1$ as the exception ob ject and $p_2$ as the stack trace. |
6018 | |
6019 \LMHash{} | |
6020 If $f$ is marked \ASYNC{} or \ASYNC* (\ref{functions}) and there is a dynamicall y enclosing exception handler (\ref{try}) $h$ introduced by the current activati on, control is transferred to $h$, otherwise $f$ terminates. | |
6021 | |
6022 \rationale{ | |
6023 In the case of an asynchronous function, the dynamically enclosing exception han dler is only relevant within the function. If an exception is not caught within the function, the exception value is channelled through a future or stream rathe r than propagating via exception handlers. | |
6024 } | |
6025 | |
6026 \LMHash{} | |
6027 Otherwise, control is transferred to the innermost enclosing exception handler. | |
6028 | |
6029 \commentary{The change in control may result in multiple functions terminating i f these functions do not catch the exception via a \CATCH{} or \FINALLY{} clause , both of which introduce a dynamically enclosing exception handler.} | |
6030 | 6160 |
6031 \LMHash{} | 6161 \LMHash{} |
6032 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit hin an \ON-\CATCH{} clause. | 6162 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit hin an \ON-\CATCH{} clause. |
6033 | 6163 |
6034 | 6164 |
6035 | |
6036 \subsection{ Try} | 6165 \subsection{ Try} |
6037 \LMLabel{try} | 6166 \LMLabel{try} |
6038 | 6167 |
6039 \LMHash{} | 6168 \LMHash{} |
6040 The try statement supports the definition of exception handling code in a struct ured way. | 6169 The try statement supports the definition of exception handling code in a struct ured way. |
6041 | 6170 |
6042 \begin{grammar} | 6171 \begin{grammar} |
6043 {\bf tryStatement:} | 6172 {\bf tryStatement:} |
6044 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) | 6173 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) |
6045 . | 6174 . |
6046 | 6175 |
6047 {\bf onPart:}catchPart block; | 6176 {\bf onPart:}catchPart block; |
6048 \ON{} type catchPart? block | 6177 \ON{} type catchPart? block |
6049 . | 6178 . |
6050 | 6179 |
6051 {\bf catchPart:} | 6180 {\bf catchPart:} |
6052 \CATCH{} `(' identifier (`,' identifier)? `)' | 6181 \CATCH{} `(' identifier (`,' identifier)? `)' |
6053 . | 6182 . |
6054 | 6183 |
6055 {\bf finallyPart:} | 6184 {\bf finallyPart:} |
6056 \FINALLY{} block | 6185 \FINALLY{} block |
6057 . | 6186 . |
6058 \end{grammar} | 6187 \end{grammar} |
6059 | 6188 |
6060 \LMHash{} | 6189 \LMHash{} |
6061 A try statement consists of a block statement, followed by at least one of: | 6190 A try statement consists of a block statement, followed by at least one of: |
6062 \begin{enumerate} | 6191 \begin{enumerate} |
6063 \item | 6192 \item |
6064 A set of \ON{}-\CATCH{} clauses, each of which specifies (either explicitly or implicitly) the type of exception object to be handled, one or two exception par ameters and a block statement. | 6193 A set of \ON{}-\CATCH{} clauses, each of which specifies (either explicitly or i mplicitly) the type of exception object to be handled, two exception parameters and a block statement. |
6065 \item | 6194 \item |
6066 A \FINALLY{} clause, which consists of a block statement. | 6195 A \FINALLY{} clause, which consists of a block statement. |
6067 \end{enumerate} | 6196 \end{enumerate} |
6068 | 6197 |
6069 \rationale{ | 6198 \rationale{ |
6070 The syntax is designed to be upward compatible with existing Javascript programs . The \ON{} clause can be omitted, leaving what looks like a Javascript catch cl ause. | 6199 The syntax is designed to be upward compatible with existing Javascript programs . The \ON{} clause can be omitted, leaving what looks like a Javascript catch cl ause. |
6071 } | 6200 } |
6072 | 6201 |
6073 \LMHash{} | 6202 \LMHash{} |
6074 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } {\em matches} an object $o$ if the type of $o$ is a subtype of $T$. If $T$ is a malformed or deferred type (\ref{staticTypes}), then performing a match ca uses a run time error. | 6203 A try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$;} is equivalent to the statement \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $\{\}$}. |
6075 | 6204 |
6076 \commentary { | 6205 \LMHash{} |
6077 It is of course a static warning if $T$ is a deferred or malformed type. | 6206 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is e quivalent to an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } where $p_2$ is an identifier that does not occur anywhere else in the program. |
6078 } | 6207 |
6208 \LMHash{} | |
6209 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ $s$} is equivalent to an \ ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$} where $p_1$ and $p_2$ are identifiers that do not occur anywhere else in the program. | |
6210 | |
6211 \LMHash{} | |
6212 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p$, $p_2$) $s$} wher e $p_2$ is an identifier that does not occur anywhere else in the program. | |
6213 | |
6214 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p_1, p_2$) $s$} is equival ent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1, p_2$) $s$ }. | |
6079 | 6215 |
6080 \LMHash{} | 6216 \LMHash{} |
6081 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. The static typ e of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}. | 6217 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. The static typ e of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}. |
6082 | 6218 |
6083 | 6219 |
6084 \LMHash{} | 6220 \LMHash{} |
6085 An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is e quivalent to an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$ } where $p_2$ is an identifier that does not occur anywhere else in the program. | 6221 Execution of a \TRY{} statement $s$ on the form: |
6086 | 6222 \begin{dartCode} |
6223 \TRY{} b | |
6224 \ON{} $T_1$ \CATCH{} ($e_1$, $t_1$) c_1 | |
6225 \ldots{} | |
6226 \ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) c_n | |
6227 \FINALLY{} f | |
6228 \end{dartCode} | |
6229 proceeds as follows: | |
6087 | 6230 |
6088 \LMHash{} | 6231 \LMHash{} |
6089 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p$) $s$}. An \ON{}- \CATCH{} clause of the form \code{\CATCH{} ($p_1, p_2$) $s$} is equivalent to a n \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1, p_2$) $s$}. | 6232 First $b$ is executed. |
6233 If execution of $b$ aborts by throwing with exception object $e$ and stack trace $t$, then $e$ and $t$ are matched against the \ON{}-\CATCH{} clauses to yield a new completion (\ref{on-catch}). | |
6090 | 6234 |
6235 Then, even if execution of $b$ aborted or matching against the \ON{}-\CATCH{} cl auses aborted, the $f$ block is executed. | |
6091 | 6236 |
6092 %If an explicit type is associated with of $p_2$, it is a static warning if that type is not \code{Object} or \DYNAMIC{}. | 6237 If execution of $f$ aborts, execution of the \TRY{} statement aborts in |
6238 the same way. | |
6239 Otherwise if execution of $b$ threw, the \TRY{} statement completes in the same way as the matching against the \ON{}-\CATCH{} clauses. | |
6240 Otherwise the \TRY{} statement completes in the same way as the execution of $b$ . | |
6241 | |
6242 \subsubsection{Matching against \ON{}-\CATCH{} clauses} | |
6243 \LMHash{} | |
6244 Matching an exception object $e$ and stack trace $t$ against a (potentially empt y) sequence of \ON{}-\CATCH{} clauses on the form: | |
6245 \begin{dartCode} | |
6246 \ON{} $T_1$ \CATCH{} ($e_1$, $st_1$) \{ $s_1$ \} | |
6247 \ldots | |
6248 \ON{} $T_n$ \CATCH{} ($e_n$, $st_n$) \{ $s_n$ \} | |
6249 \end{dartCode} | |
6093 | 6250 |
6094 \LMHash{} | 6251 \LMHash{} |
6095 The {\em active stack trace} is an object whose \code{toString()} method produce s a string that is a record of exactly those function activations within the cur rent isolate that had not completed execution at the point where the current exc eption (\ref{throw}) was thrown. | 6252 If there are no \ON{}-\CATCH{} clauses ($n = 0$), matching completes by {\em thr owing} the exception object $e$ and stack trace $t$. |
6096 %\begin{enumerate} | |
6097 %\item Started execution after the currently executing function. | |
6098 %\item Had not completed execution at the point where the exception caught by th e currently executing \ON{}-\CATCH{} clause was initially thrown. | |
6099 %\commentary{The active stack trace contains the frames between the exception ha ndling code and the original point when an exception is thrown, not where it was rethrown.} | |
6100 %\end{enumerate} | |
6101 | 6253 |
6102 \commentary{ | 6254 Otherwise the exception is matched against the first clause. |
6103 This implies that no synthetic function activations may be added to the trace, n or may any source level activations be omitted. | 6255 \LMHash{} |
6104 This means, for example, that any inlining of functions done as an optimization must not be visible in the trace. Similarly, any synthetic routines used by the implementation must not appear in the trace. | |
6105 | 6256 |
6106 Nothing is said about how any native function calls may be represented in the tr ace. | 6257 If $T_1$ is a malformed or deferred type (\ref{staticTypes}), then performing a match causes a run time error. |
6107 } | 6258 \commentary { |
6108 | 6259 It is of course a static warning if $T_i$, $1 \le i \le n$ is a deferred or malf ormed type. |
6109 \commentary{ | |
6110 Note that we say nothing about the identity of the stack trace, or what notion o f equality is defined for stack traces. | |
6111 } | |
6112 | |
6113 % Sadly, the info below cannot be computed efficiently. It would need to be comp uted at the throw point, since at latte points it might be destroyed. Native cod e in calling frames executes relative to the stack pointer, which therefore need s to be reset as each frame is unwound. This means that the | |
6114 % OS kernel can dispose of this stack memory - it is not reliably preserved. And such code must execute if only to test if the exception should be caught or sen t onward. | |
6115 | |
6116 % For each such function activation, the active stack trace includes the name of the function, the bindings of all its formal parameters, local variables and \T HIS{}, and the position at which the function was executing. | |
6117 | |
6118 % Is this controversial? We were thinking of viewing the trace as a List<Invoca tion>, | |
6119 % but that won't capture the receiver or the locals. More generally, we need a standard interface that describes these traces, so one can type the stack trace variable in the catch. | |
6120 | |
6121 \commentary{The term position should not be interpreted as a line number, but r ather as a precise position - the exact character index of the expression that raised the exception. } | |
6122 | |
6123 % A position can be represented via a Token. If we make that part of the core r eflection facility, we can state this here. | |
6124 | |
6125 \LMHash{} | |
6126 A try statement \TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $s_f$ d efines an exception handler $h$ that executes as follows: | |
6127 | |
6128 \LMHash{} | |
6129 The \ON{}-\CATCH{} clauses are examined in order, starting with $catch_1$, until either an \ON{}-\CATCH{} clause that matches the current exception (\ref{throw} ) is found, or the list of \ON{}-\CATCH{} clauses has been exhausted. If an \ON{ }-\CATCH{} clause $on-catch_k$ is found, then $p_{k1}$ is bound to the current e xception, $p_{k2}$, if declared, is bound to the active stack trace, and then $catch_k$ is executed. If no \ON{}-\CATCH{} clause is found, the \FINALLY{} clau se is executed. Then, execution resumes at the end of the try statement. | |
6130 | |
6131 | |
6132 \LMHash{} | |
6133 A finally clause \FINALLY{} $s$ defines an exception handler $h$ that executes a s follows: | |
6134 | |
6135 \LMHash{} | |
6136 Let $r$ be the current return value (\ref{return}). Then the current return valu e becomes undefined. Any open streams associated with any asynchronous for loops (\ref{asynchronousFor-in}) and yield-each (\ref{yieldEach}) statements executin g within the dynamic scope of $h$ are canceled, in the order of their nesting, i nnermost first. | |
6137 | |
6138 \rationale{ | |
6139 Streams left open by for loops that were escaped for whatever reason would be ca nceled at function termination, but it is best to cancel them as soon as possibl e. | |
6140 } | 6260 } |
6141 | 6261 |
6142 \LMHash{} | 6262 \LMHash{} |
6143 Then the \FINALLY{} clause is executed. Let $m$ be the immediately enclosing fun ction. If $r$ is defined then the current return value is set to $r$ and then: | 6263 Otherwise, if the type of $e$ is a subtype of $T_1$, then the first clause match es, and then $e_1$ is bound to the exception object $e$ and $t_1$ is bound to th e stack trace $t$, and $s_1$ is executed in this scope. |
6144 \begin{itemize} | 6264 The matching completes in the same way as this execution. |
6145 \item | |
6146 if there is a dynamically enclosing error handler $g$ defined by a \FINALLY{} c lause in $m$, control is transferred to $g$. | |
6147 \item | |
6148 Otherwise $m$ terminates. | |
6149 \end{itemize} | |
6150 | |
6151 Otherwise, execution resumes at the end of the try statement. | |
6152 | 6265 |
6153 \LMHash{} | 6266 \LMHash{} |
6154 Execution of an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} $ s$ of a try statement $t$ proceeds as follows: The statement $s$ is executed in the dynamic scope of the exception handler defined by the finally clause of $t$. Then, the current exception and active stack trace both become undefined. | 6267 Otherwise, if the first clause did not match $e$, $e$ and $t$ are recursively ma tched against the remaining \ON{}-\CATCH{} clauses: |
6155 | 6268 \begin{dartCode} |
6156 \LMHash{} | 6269 \ON{} $T_2$ \CATCH{} ($e_2$, $t_2$) \{ $s_2$ \} |
6157 Execution of a \FINALLY{} clause \FINALLY{} $s$ of a try statement proceeds as f ollows: | 6270 \ldots |
6158 | 6271 \ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) \{ $s_n$ \} |
6159 \LMHash{} | 6272 \end{dartCode} |
6160 Let $x$ be the current exception and let $t$ be the active stack trace. Then the current exception and the active stack trace both become undefined. The stateme nt $s$ is executed. Then, if $x$ is defined, it is rethrown as if by a rethrow statement (\ref{rethrow}) enclosed in a \CATCH{} clause of the form \code{\CATCH {} ($v_x$, $v_t$)} where $v_x$ and $v_t$ are fresh variables bound to $x$ and $t $ respectively. | |
6161 | |
6162 | |
6163 \LMHash{} | |
6164 Execution of a try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots o n-catch_n$ \FINALLY{} $s_f$;} proceeds as follows: | |
6165 | |
6166 \LMHash{} | |
6167 The statement $s_1$ is executed in the dynamic scope of the exception handler de fined by the try statement. Then, the \FINALLY{} clause is executed. | |
6168 | |
6169 \commentary{ | |
6170 Whether any of the \ON{}-\CATCH{} clauses is executed depends on whether a match ing exception has been raised by $s_1$ (see the specification of the throw state ment). | |
6171 | |
6172 If $s_1$ has raised an exception, it will transfer control to the try statement' s handler, which will examine the catch clauses in order for a match as specifie d above. If no matches are found, the handler will execute the \FINALLY{} clause . | |
6173 | |
6174 If a matching \ON{}-\CATCH{} was found, it will execute first, and then the \FIN ALLY{} clause will be executed. | |
6175 | |
6176 If an exception is thrown during execution of an \ON{}-\CATCH{} clause, this wil l transfer control to the handler for the \FINALLY{} clause, causing the \FINALL Y{} clause to execute in this case as well. | |
6177 | |
6178 If no exception was raised, the \FINALLY{} clause is also executed. Execution of the \FINALLY{} clause could also raise an exception, which will cause transfer of control to the next enclosing handler. | |
6179 } | |
6180 | |
6181 \LMHash{} | |
6182 A try statement of the form \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$;} is equivalent to the statement \code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $\{\}$}. | |
6183 | 6273 |
6184 | 6274 |
6185 \subsection{ Return} | 6275 \subsection{ Return} |
6186 \LMLabel{return} | 6276 \LMLabel{return} |
6187 | 6277 |
6188 \LMHash{} | 6278 \LMHash{} |
6189 The {\em return statement} returns a result to the caller of a synchronous funct ion, completes the future associated with an asynchronous function or terminate s the stream or iterable associated with a generator (\ref{functions}). | 6279 The {\em return statement} returns a result to the caller of a synchronous funct ion, completes the future associated with an asynchronous function or terminate s the stream or iterable associated with a generator (\ref{functions}). |
6190 | 6280 |
6191 | 6281 |
6192 \begin{grammar} | 6282 \begin{grammar} |
6193 {\bf returnStatement:} | 6283 {\bf returnStatement:} |
6194 \RETURN{} expression? `{\escapegrammar ;}' % could do top level here | 6284 \RETURN{} expression? `{\escapegrammar ;}' % could do top level here |
6195 . | 6285 . |
6196 \end{grammar} | 6286 \end{grammar} |
6197 | 6287 |
6198 \commentary{ | |
6199 Due to \FINALLY{} clauses, the precise behavior of \RETURN{} is a little more i nvolved. Whether the value a return statement is supposed to return is actually returned depends on the behavior of any \FINALLY{} clauses in effect when execut ing the return. A \FINALLY{} clause may choose to return another value, or throw an exception, or even redirect control flow leading to other returns or throws. All a return statement really does is set a value that is intended to be return ed when the function terminates. | |
6200 } | |
6201 | |
6202 \LMHash{} | |
6203 The {\em current return value} is a unique value specific to a given function ac tivation. It is undefined unless explicitly set in this specification. | |
6204 | |
6205 \LMHash{} | 6288 \LMHash{} |
6206 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows: | 6289 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows: |
6207 | 6290 |
6208 \LMHash{} | 6291 \LMHash{} |
6209 First the expression $e$ is evaluated, producing an object $o$. Next: | 6292 First the expression $e$ is evaluated, producing an object $o$. |
6210 \begin{itemize} | 6293 Then the return statement completes by \em{returning} $o$. |
6211 \item | |
6212 The current return value is set to $o$ and the current exception (\ref{throw}) a nd active stack trace (\ref{try}) become undefined. | |
6213 \item | |
6214 Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statemen t (\ref{try}), if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. | |
6215 \item | |
6216 Otherwise execution of the current method terminates. | |
6217 \end{itemize} | |
6218 | |
6219 \commentary{ | |
6220 In the simplest case, the immediately enclosing function is an ordinary, synchro nous non-generator, and upon function termination, the current return value is g iven to the caller. The other possibility is that the function is marked \ASYNC {}, in which case the current return value is used to complete the future associ ated with the function invocation. Both these scenarios are specified in section \ref{functionInvocation}. | |
6221 The enclosing function cannot be marked as generator (i.e, \ASYNC* or \SYNC*), s ince generators are not allowed to contain a statement of the form \code{\RETURN {} $e$;} as discussed below. | |
6222 } | |
6223 | 6294 |
6224 \LMHash{} | 6295 \LMHash{} |
6225 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. | 6296 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. |
6226 | 6297 |
6227 \LMHash{} | 6298 \LMHash{} |
6228 It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \ code{Future$<$flatten(T)$>$} (\ref{functionExpressions}) may not be assigned to the declared return type of $f$. Otherwise, it is a static type warning if $T $ may not be assigned to the declared return type of $f$. | 6299 It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \ code{Future$<$flatten(T)$>$} (\ref{functionExpressions}) may not be assigned to the declared return type of $f$. Otherwise, it is a static type warning if $T $ may not be assigned to the declared return type of $f$. |
6229 | 6300 |
6230 \LMHash{} | 6301 \LMHash{} |
6231 Let $S$ be the runtime type of $o$. In checked mode: | |
6232 \begin{itemize} | |
6233 \item If the body of $f$ is marked \ASYNC{} (\ref{functions}) it is a dynamic t ype error if $o$ is not \NULL{} (\ref{null}) and \code{Future$<$flatten(S)$>$} i s not a subtype of the actual return type (\ref{actualTypeOfADeclaration}) of $ f$. | |
6234 \item Otherwise, it is a dynamic type error if $o$ is not \NULL{} and the runtim e type of $o$ is not a subtype of the actual return type of $f$. | |
6235 \end{itemize} | |
6236 | |
6237 \LMHash{} | |
6238 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generative constructor (\ref{generativeConstructors}). | 6302 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generative constructor (\ref{generativeConstructors}). |
6239 | 6303 |
6240 \rationale{ | 6304 \rationale{ |
6241 It is quite easy to forget to add the factory prefix for a constructor, accident ally converting a factory into a generative constructor. The static checker may detect a type mismatch in some, but not all, of these cases. The rule above help s catch such errors, which can otherwise be very hard to recognize. There is no real downside to it, as returning a value from a generative constructor is meani ngless. | 6305 It is quite easy to forget to add the factory prefix for a constructor, accident ally converting a factory into a generative constructor. The static checker may detect a type mismatch in some, but not all, of these cases. The rule above help s catch such errors, which can otherwise be very hard to recognize. There is no real downside to it, as returning a value from a generative constructor is meani ngless. |
6242 } | 6306 } |
6243 | 6307 |
6244 \LMHash{} | 6308 \LMHash{} |
6245 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generator function. | 6309 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$ ;} appears in a generator function. |
6246 | 6310 |
6247 \rationale{ | 6311 \rationale{ |
6248 In the case of a generator function, the value returned by the function is the i terable or stream associated with it, and individual elements are added to that iterable using yield statements, and so returning a value makes no sense. | 6312 In the case of a generator function, the value returned by the function is the i terable or stream associated with it, and individual elements are added to that iterable using yield statements, and so returning a value makes no sense. |
6249 } | 6313 } |
6250 | 6314 |
6251 \LMHash{} | 6315 \LMHash{} |
6252 Let $f$ be the function immediately enclosing a return statement of the form \RE TURN{}; It is a static warning $f$ is neither a generator nor a generative cons tructor and either: | 6316 Let $f$ be the function immediately enclosing a return statement of the form \RE TURN{}; It is a static warning $f$ is neither a generator nor a generative cons tructor and either: |
6253 \begin{itemize} | 6317 \begin{itemize} |
6254 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOI D{} (\ref{typeVoid}) or, | 6318 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOI D{} (\ref{typeVoid}) or, |
6255 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \co de{Future$<$Null$>$}. | 6319 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \co de{Future$<$Null$>$}. |
6256 \end{itemize} | 6320 \end{itemize} |
6257 | 6321 |
6258 \commentary{ | 6322 \commentary{ |
6259 Hence, a static warning will not be issued if $f$ has no declared return type, s ince the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VO ID{} and to \code{Future$<$Null$>$}. However, any synchronous non-generator func tion that declares a return type must return an expression explicitly. | 6323 Hence, a static warning will not be issued if $f$ has no declared return type, s ince the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VO ID{} and to \code{Future$<$Null$>$}. However, any synchronous non-generator func tion that declares a return type must return an expression explicitly. |
6260 } | 6324 } |
6261 \rationale{This helps catch situations where users forget to return a value in a return statement.} | 6325 \rationale{This helps catch situations where users forget to return a value in a return statement.} |
6262 | 6326 |
6263 \rationale{ An asynchronous non-generator always returns a future of some sort. If no expression is given, the future will be completed with \NULL{} and this mo tivates the requirement above.} \commentary{Leaving the return type of a functio n marked \ASYNC{} blank will be interpreted as \DYNAMIC{} as always, and cause no type error. Using \code{Future} or \code{Future$<$Object$>$} is acceptable as well, but any other type will cause a warning, since \NULL{} has no subtypes.} | 6327 \rationale{ An asynchronous non-generator always returns a future of some sort. If no expression is given, the future will be completed with \NULL{} and this mo tivates the requirement above.} \commentary{Leaving the return type of a functio n marked \ASYNC{} blank will be interpreted as \DYNAMIC{} as always, and cause no type error. Using \code{Future} or \code{Future$<$Object$>$} is acceptable as well, but any other type will cause a warning, since \NULL{} has no subtypes.} |
6264 | 6328 |
6265 \LMHash{} | 6329 \LMHash{} |
6266 A return statement with no expression, \code{\RETURN;} is executed as follows: | 6330 A return statement with no expression, \code{\RETURN;} is executed |
6331 by {\em returning} with no value (\ref{completion}). | |
6267 | 6332 |
6268 \LMHash{} | |
6269 If the immediately enclosing function $f$ is a generator, then: | |
6270 \begin{itemize} | |
6271 \item | |
6272 The current return value is set to \NULL{}. | |
6273 \item | |
6274 Let $c$ be the \FINALLY{} clause of the innermost enclosing try-finally statemen t, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. | |
6275 \item | |
6276 Otherwise, execution of the current method terminates. | |
6277 \end{itemize} | |
6278 | |
6279 \LMHash{} | |
6280 Otherwise the return statement is executed by executing the statement \code{\RE TURN{} \NULL{};} if it occurs inside a method, getter, setter or factory; otherw ise, the return statement necessarily occurs inside a generative constructor, in which case it is executed by executing \code{\RETURN{} \THIS{};}. | |
6281 | |
6282 \commentary{Despite the fact that \code{\RETURN{};} is executed as if by a \code {\RETURN{} $e$;}, it is important to understand that it is not a static warning to include a statement of the form \code{\RETURN{};} | |
6283 %in a \VOID{} function; neither is it illegal | |
6284 in a generative constructor. The rules relate only to the specific syntactic for m \code{\RETURN{} $e$;}. | |
6285 } | |
6286 | |
6287 | |
6288 \rationale{ | |
6289 The motivation for formulating \code{\RETURN{};} in this way stems from the basi c requirement that all function invocations indeed return a value. Function invo cations are expressions, and we cannot rely on a mandatory typechecker to always prohibit use of \VOID{} functions in expressions. Hence, a return statement mus t always return a value, even if no expression is specified. | |
6290 | |
6291 The question then becomes, what value should a return statement return when no r eturn expression is given. In a generative constructor, it is obviously the obje ct being constructed (\THIS{}). A void function is not expected to participate i n an expression, which is why it is marked \VOID{} in the first place. Hence, th is situation is a mistake which should be detected as soon as possible. The stat ic rules help here, but if the code is executed, using \NULL{} leads to fast fai lure, which is desirable in this case. The same rationale applies for function b odies that do not contain a return statement at all. | |
6292 } | |
6293 | 6333 |
6294 \LMHash{} | 6334 \LMHash{} |
6295 It is a static warning if a function contains both one or more explicit return statements of the form \code{\RETURN;} and one or more return statements of the form \code{\RETURN{} $e$;}. | 6335 It is a static warning if a function contains both one or more explicit return statements of the form \code{\RETURN;} and one or more return statements of the form \code{\RETURN{} $e$;}. |
6296 | 6336 |
6297 | 6337 |
6298 | |
6299 | |
6300 \subsection{ Labels} | 6338 \subsection{ Labels} |
6301 \LMLabel{labels} | 6339 \LMLabel{labels} |
6302 | 6340 |
6303 \LMHash{} | 6341 \LMHash{} |
6304 A {\em label} is an identifier followed by a colon. A {\em labeled statement} is a statement prefixed by a label $L$. A {\em labeled case clause} is a case cla use within a switch statement (\ref{switch}) prefixed by a label $L$. | 6342 A {\em label} is an identifier followed by a colon. A {\em labeled statement} is a statement prefixed by a label $L$. A {\em labeled case clause} is a case cla use within a switch statement (\ref{switch}) prefixed by a label $L$. |
6305 | 6343 |
6306 \rationale{The sole role of labels is to provide targets for the break (\ref{bre ak}) and continue (\ref{continue}) statements.} | 6344 \rationale{The sole role of labels is to provide targets for the break (\ref{bre ak}) and continue (\ref{continue}) statements.} |
6307 | 6345 |
6308 %\Q{Are labels in a separate namespace? Bug 49774299} | 6346 %\Q{Are labels in a separate namespace? Bug 49774299} |
6309 | 6347 |
6310 \begin{grammar} | 6348 \begin{grammar} |
6311 {\bf label:} | 6349 {\bf label:} |
6312 identifier `{\escapegrammar :}' | 6350 identifier `{\escapegrammar :}' |
6313 . | 6351 . |
6314 \end{grammar} | 6352 \end{grammar} |
6315 | 6353 |
6316 \LMHash{} | 6354 \LMHash{} |
6317 The semantics of a labeled statement $L: s$ are identical to those of the state ment $s$. The namespace of labels is distinct from the one used for types, funct ions and variables. | 6355 Execution a labeled statement $s$, $label: s_l$, consists of executing $s_l$. |
6356 If execution of $s_l$ aborts by {\em breaking} with the label $label$, | |
6357 then execution of $s$ completes normally, | |
6358 otherwise execution of $s$ aborts in the same ways as $sl$. | |
6359 | |
6360 The namespace of labels is distinct from the one used for types, functions and v ariables. | |
6318 | 6361 |
6319 \LMHash{} | 6362 \LMHash{} |
6320 The scope of a label that labels a statement $s$ is $s$. The scope of a label th at labels a case clause of a switch statement $s$ is $s$. | 6363 The scope of a label that labels a statement $s$ is $s$. The scope of a label th at labels a case clause of a switch statement $s$ is $s$. |
6321 | 6364 |
6322 \rationale{Labels should be avoided by programmers at all costs. The motivation for including labels in the language is primarily making Dart a better target fo r code generation. | 6365 \rationale{Labels should be avoided by programmers at all costs. The motivation for including labels in the language is primarily making Dart a better target fo r code generation. |
6323 } | 6366 } |
6324 | 6367 |
6325 | 6368 |
6326 \subsection{ Break} | 6369 \subsection{ Break} |
6327 \LMLabel{break} | 6370 \LMLabel{break} |
6328 | 6371 |
6329 \LMHash{} | 6372 \LMHash{} |
6330 The {\em break statement} consists of the reserved word \BREAK{} and an optional label (\ref{labels}). | 6373 The {\em break statement} consists of the reserved word \BREAK{} and an optional label (\ref{labels}). |
6331 | 6374 |
6332 \begin{grammar} | 6375 \begin{grammar} |
6333 {\bf breakStatement:} | 6376 {\bf breakStatement:} |
6334 \BREAK{} identifier? `{\escapegrammar ;}' | 6377 \BREAK{} identifier? `{\escapegrammar ;}' |
6335 . | 6378 . |
6336 \end{grammar} | 6379 \end{grammar} |
6337 | 6380 |
6338 \LMHash{} | 6381 \LMHash{} |
6339 Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form \code{\BREAK{} $L$;} , then let $s_E$ be the innermost labeled statement with label $L$ enclosing $s_ b$. If $s_b$ is of the form \code{\BREAK{};}, then let $s_E$ be the innermost \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) or \WHILE{} (\ref {while}) statement enclosing $s_b$. It is a compile-time error if no such state ment $s_E$ exists within the innermost function in which $s_b$ occurs. Further more, let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed i n $s_E$ and that enclose $s_b$, and that have a \FINALLY{} clause. Lastly, let $f_j$ be the \FINALLY{} clause of $s_j, 1 \le j \le n$. Executing $s_b$ first executes $f_1, \ldots, f_n$ in innermost-clause-first order and then terminat es $s_E$. | 6382 Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form \code{\BREAK{} $L$;} , then let $s_E$ be the innermost labeled statement with label $L$ enclosing $s_ b$. If $s_b$ is of the form \code{\BREAK{};}, then let $s_E$ be the innermost \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) or \WHILE{} (\ref {while}) statement enclosing $s_b$. It is a compile-time error if no such state ment $s_E$ exists within the innermost function in which $s_b$ occurs. |
6340 | 6383 |
6341 \LMHash{} | 6384 \LMHash{} |
6342 If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), its associated stream subscription is canceled. Furthermore, let $a_k$ be the set of asynchrono us for loops and yield-each statements (\ref{yieldEach}) enclosing $s_b$ that a re enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$. Th e stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, inne rmost first, so that $a_j$ is canceled before $a_{j+1}$. | 6385 Execution of a \BREAK{} statement \code{\BREAK{} label;} completes by {\em break ing} with the label \code{label} (\ref{completion}). |
6343 | 6386 |
6387 Execution of a \BREAK{} statement \code{\BREAK{};} completes by {\em breaking} w ithout a label (\ref{completion}). | |
6344 | 6388 |
6345 | 6389 |
6346 \subsection{ Continue} | 6390 \subsection{ Continue} |
6347 \LMLabel{continue} | 6391 \LMLabel{continue} |
6348 | 6392 |
6349 \LMHash{} | 6393 \LMHash{} |
6350 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op tional label (\ref{labels}). | 6394 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op tional label (\ref{labels}). |
6351 | 6395 |
6352 \begin{grammar} | 6396 \begin{grammar} |
6353 {\bf continueStatement:} | 6397 {\bf continueStatement:} |
6354 \CONTINUE{} identifier? `{\escapegrammar ;}' | 6398 \CONTINUE{} identifier? `{\escapegrammar ;}' |
6355 . | 6399 . |
6356 \end{grammar} | 6400 \end{grammar} |
6357 | 6401 |
6358 \LMHash{} | 6402 \LMHash{} |
6359 Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form \code{\CONTINUE{ } $L$;}, then let $s_E$ be the innermost labeled \DO{} (\ref{do}), \FOR{} (\ref{ for}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ enclosin g $s_c$. If $s_c$ is of the form \code{\CONTINUE{};} then let $s_E$ be the inne rmost \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement enclosing $s_c$. It is a compile-time error if no such statement or case clause $s_E$ exists within the innermost function in which $s_c$ occurs. Furthermore , let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclosed in $s _E$ and that enclose $s_c$, and that have a \FINALLY{} clause. Lastly, let $f_j $ be the \FINALLY{} clause of $s_j, 1 \le j \le n$. Executing $s_c$ first exe cutes $f_1, \ldots, f_n$ in innermost-clause-first order. Then, if $s_E$ is a case clause, control is transferred to the case clause. Otherwise, $s_E$ is nece ssarily a loop and execution resumes after the last statement in the loop body. | 6403 Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form \code{\CONTINUE{} $L$;}, then let $s_E$ be the innermost labeled \DO{} (\ref{do}), \FOR{} (\ref{f or}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ enclosing $s_c$. If $s_c$ is of the form \code{\CONTINUE{};} then let $s_E$ be the inner most \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) statement e nclosing $s_c$. It is a compile-time error if no such statement or case clause $s_E$ exists within the innermost function in which $s_c$ occurs. |
6360 | 6404 |
6361 \commentary{ | 6405 Execution of a \CONTINUE{} statement \code{\CONTINUE{} label;} completes by {\em continuing} with the label \code{label} (\ref{completion}). |
6362 In a while loop, that would be the boolean expression before the body. In a do loop, it would be the boolean expression after the body. In a for loop, it would be the increment clause. In other words, execution continues to the next itera tion of the loop. | 6406 |
6363 } | 6407 Execution of a \CONTINUE{} statement \code{\CONTINUE{};} completes by {\em conti nuing} without a label (\ref{completion}). |
6408 | |
6409 | |
6410 \subsection{ Yield and Yield-Each} | |
6411 \LMLabel{yieldAndYieldEach} | |
6412 | |
6413 \subsubsection{ Yield} | |
6414 \LMLabel{yield} | |
6364 | 6415 |
6365 \LMHash{} | 6416 \LMHash{} |
6366 If $s_E$ is an asynchronous for loop (\ref{asynchronousFor-in}), let $a_k$ be t he set of asynchronous for loops and yield-each statements (\ref{yieldEach}) enc losing $s_c$ that are enclosed in $s_E , 1 \le k \le m$, where $a_k$ is enclosed in $a_{k+1}$. The stream subscriptions associated with $a_j$ are canceled, $1 \le j \le m$, innermost first, so that $a_j$ is canceled before $a_{j+1}$. | 6417 The {\em yield statement} adds an element to the result of a generator function (\ref{functions}). |
6367 | 6418 |
6368 \subsection{ Yield and Yield-Each} | 6419 \begin{grammar} |
6369 \LMLabel{yieldAndYieldEach} | |
6370 | |
6371 \subsubsection{ Yield} | |
6372 \LMLabel{yield} | |
6373 | |
6374 \LMHash{} | |
6375 The {\em yield statement} adds an element to the result of a generator function (\ref{functions}). | |
6376 | |
6377 \begin{grammar} | |
6378 {\bf yieldStatement:} | 6420 {\bf yieldStatement:} |
6379 \YIELD{} expression `{\escapegrammar ;}' | 6421 \YIELD{} expression `{\escapegrammar ;}' |
6380 . | 6422 . |
6381 \end{grammar} | 6423 \end{grammar} |
6382 | 6424 |
6383 \LMHash{} | 6425 \LMHash{} |
6384 Execution of a statement $s$ of the form \code{\YIELD{} $e$;} proceeds as follo ws: | 6426 Execution of a statement $s$ of the form \code{\YIELD{} $e$;} proceeds as follo ws: |
6385 | 6427 |
6386 \LMHash{} | 6428 \LMHash{} |
6387 First, the expression $e$ is evaluated to an object $o$. If the enclosing functi on $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m $ has been paused, then execution of $m$ is suspended until $u$ is resumed or c anceled. | 6429 First, the expression $e$ is evaluated to an object $o$. If the enclosing functi on $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m $ has been paused, then the nearest enclosing asynchronous for loop (\ref{asynch ronousFor-in}), if any, is paused and execution of $m$ is suspended until $u$ is resumed or canceled. |
6388 | 6430 |
6389 \LMHash{} | 6431 \LMHash{} |
6390 Next, $o$ is added to the iterable or stream associated with the immediately enc losing function. | 6432 Next, $o$ is added to the iterable or stream associated with the immediately enc losing function. |
6391 | 6433 |
6392 \LMHash{} | 6434 \LMHash{} |
6393 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi th $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of t he innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$ . If $h$ is undefined, the immediately enclosing function terminates. | 6435 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi th $m$ has been canceled, then the \YIELD{} statement completes by {\em returnin g} without a value (\ref{completion}), otherwise it completes normally. |
6394 | 6436 |
6395 \rationale{ | 6437 \rationale{ |
6396 The stream associated with an asynchronous generator could be canceled by any co de with a reference to that stream at any point where the generator was passivat ed. Such a cancellation constitutes an irretrievable error for the generator. A t this point, the only plausible action for the generator is to clean up after i tself via its \FINALLY{} clauses. | 6438 The stream associated with an asynchronous generator could be canceled by any co de with a reference to that stream at any point where the generator was passivat ed. Such a cancellation constitutes an irretrievable error for the generator. A t this point, the only plausible action for the generator is to clean up after i tself via its \FINALLY{} clauses. |
6397 } | 6439 } |
6398 | 6440 |
6399 \LMHash{} | 6441 \LMHash{} |
6400 Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) the n the enclosing function may suspend. | 6442 Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) the n the enclosing function may suspend, in which case the nearest enclosing asynch ronous for loop (\ref{asynchronousFor-in}), if any, is paused first. |
6401 | 6443 |
6402 \rationale { | 6444 \rationale { |
6403 If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the enclosing str eam to run and access the data in the stream. The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we al low the enclosing function to be suspended when a new value is added to its asso ciated stream. However, it is not essential (and in fact, can be quite costly) t o suspend the function on every \YIELD{}. The implementation is free to decide h ow often to suspend the enclosing function. The only requirement is that consume rs are not blocked indefinitely. | 6445 If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the enclosing str eam to run and access the data in the stream. The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we al low the enclosing function to be suspended when a new value is added to its asso ciated stream. However, it is not essential (and in fact, can be quite costly) t o suspend the function on every \YIELD{}. The implementation is free to decide h ow often to suspend the enclosing function. The only requirement is that consume rs are not blocked indefinitely. |
6404 } | 6446 } |
6405 | 6447 |
6406 | 6448 |
6407 \LMHash{} | 6449 \LMHash{} |
6408 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: | 6450 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: |
6409 \begin{itemize} | 6451 \begin{itemize} |
6410 \item | 6452 \item |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6443 | 6485 |
6444 \LMHash{} | 6486 \LMHash{} |
6445 First, the expression $e$ is evaluated to an object $o$. | 6487 First, the expression $e$ is evaluated to an object $o$. |
6446 | 6488 |
6447 \LMHash{} | 6489 \LMHash{} |
6448 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th en: | 6490 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th en: |
6449 \begin{enumerate} | 6491 \begin{enumerate} |
6450 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl e}. Otherwise | 6492 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl e}. Otherwise |
6451 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$. | 6493 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$. |
6452 \item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Other wise | 6494 \item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Other wise |
6453 \item The getter \cd{current} is invoked on $i$. If the invocation raises an exc eption $ex$, execution of $s$ throws $ex$. Otherwise, the result $x$ of the gett er invocation is added to the iterable associated with $m$. | 6495 \item The getter \cd{current} is invoked on $i$. If the invocation {\em throws} an exception $ex$, execution of $s$ aborts in the same way. Otherwise, the resul t $x$ of the getter invocation is added to the iterable associated with $m$. |
Kevin Millikin (Google)
2016/10/13 12:18:37
I've always thought that calling current here is w
Lasse Reichstein Nielsen
2016/10/17 10:08:23
This is the *simple* implementation which is basic
| |
6454 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$, at which point execution of $s$ continues at \ref{m oveNext}. | 6496 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$, at which point execution of $s$ continues at \ref{m oveNext}. |
6455 \item | 6497 \item |
6456 The current call to \code{moveNext()} returns \TRUE. | 6498 The current call to \code{moveNext()} returns \TRUE. |
6457 \end{enumerate} | 6499 \end{enumerate} |
6458 | 6500 |
6459 \LMHash{} | 6501 \LMHash{} |
6460 If $m$ is marked \ASYNC* (\ref{functions}), then: | 6502 If $m$ is marked \ASYNC* (\ref{functions}), then: |
6461 \begin{itemize} | 6503 \begin{itemize} |
6462 \item It is a dynamic error if the class of $o$ does not implement \code{Stream }. Otherwise | 6504 \item It is a dynamic error if the class of $o$ does not implement \code{Stream }. Otherwise |
6463 \item For each element $x$ of $o$: | 6505 \item The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused. |
6506 \item The $o$ stream is listened to, creating a subscription $s$, and for each e vent $x$, or error $e$ with stack trace $t$, of $s$: | |
6464 \begin{itemize} | 6507 \begin{itemize} |
6465 \item | 6508 \item |
6466 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled. | 6509 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled. |
6467 \item | |
6468 If the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FI NALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is define d, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates. | |
6469 \item | 6510 \item |
6470 Otherwise, $x$ is added to the stream associated with $m$ in the order it appea rs in $o$. The function $m$ may suspend. | 6511 If the stream $u$ associated with $m$ has been canceled, |
6512 then $s$ is canceled by evaluating \code{\AWAIT{} v.cancel()} where $v$ is a fre sh variable referencing the stream subscription $s$. | |
6513 Then, if the cancel completed normally, the stream execution of $s$ aborts by {\ em returning} with no value (\ref{completion}). | |
6514 \item | |
6515 Otherwise, $x$, or $e$ with $t$, are added to the stream associated with $m$ in the order they appears in $o$. The function $m$ may suspend. | |
6471 \end{itemize} | 6516 \end{itemize} |
6472 \item If the stream $o$ is done, execution of $s$ is complete. | 6517 \item If the stream $o$ is done, execution of $s$ completes normally. |
6473 \end{itemize} | 6518 \end{itemize} |
6474 | 6519 |
6475 | 6520 |
6476 \LMHash{} | 6521 \LMHash{} |
6477 It is a compile-time error if a yield-each statement appears in a function that is not a generator function. | 6522 It is a compile-time error if a yield-each statement appears in a function that is not a generator function. |
6478 | 6523 |
6479 \LMHash{} | 6524 \LMHash{} |
6480 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if $T$ may not be assigned to the declared ret urn type of $f$. If $f$ is synchronous it is a static type warning if $T$ may not be assigned to \code{Iterable}. If $f$ is asynchronous it is a static type warning if $T$ may not be assigned to \code{Stream}. | 6525 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if $T$ may not be assigned to the declared ret urn type of $f$. If $f$ is synchronous it is a static type warning if $T$ may not be assigned to \code{Iterable}. If $f$ is asynchronous it is a static type warning if $T$ may not be assigned to \code{Stream}. |
6481 | 6526 |
6482 | 6527 |
6483 \subsection{ Assert} | 6528 \subsection{ Assert} |
6484 \LMLabel{assert} | 6529 \LMLabel{assert} |
6485 | 6530 |
6486 \LMHash{} | 6531 \LMHash{} |
6487 An {\em assert statement} is used to disrupt normal execution if a given boolean condition does not hold. | 6532 An {\em assert statement} is used to disrupt normal execution if a given boolean condition does not hold. |
6488 | 6533 |
6489 \begin{grammar} | 6534 \begin{grammar} |
6490 {\bf assertStatement:} | 6535 {\bf assertStatement:} |
6491 assert `(' expression `)' `{\escapegrammar ;}' | 6536 assert `(' expression `)' `{\escapegrammar ;}' |
6492 . | 6537 . |
6493 \end{grammar} | 6538 \end{grammar} |
6494 | 6539 |
6495 \LMHash{} | 6540 \LMHash{} |
6496 The assert statement has no effect in production mode. In checked mode, executio n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: | 6541 The assert statement has no effect in production mode. In checked mode, executio n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: |
6497 | 6542 |
6498 \LMHash{} | 6543 \LMHash{} |
6499 The expression $e$ is evaluated to an object $o$. If the class of $o$ is a subty pe of \code{Function} then let $r$ be the result of invoking $o$ with no argumen ts. Otherwise, let $r$ be $o$. | 6544 The expression $e$ is evaluated to an object $o$. If the class of $o$ is a subty pe of \code{Function} then let $r$ be the result of invoking $o$ with no argumen ts. Otherwise, let $r$ be $o$. |
6500 It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Fu nction}, or if $r$ is not of type \code{bool}. If $r$ is \FALSE{}, we say that the assertion failed. If $r$ is \TRUE{}, we say that the assertion succeeded. If the assertion succeeded, execution of the assert statement is complete. If the assertion failed, an \code{AssertionError} is thrown. | 6545 It is a dynamic type error if $o$ is not of type \code{bool} or of type \code{Fu nction}, or if $r$ is not of type \code{bool}. If $r$ is \FALSE{}, we say that the assertion failed. If $r$ is \TRUE{}, we say that the assertion succeeded. If the assertion succeeded, execution of the assert statement is complete. If the assertion failed, the execution {\em throws} an \code{AssertionError} with a sta ck trace corresponding to the \ASSERT{} statement. |
6501 | 6546 |
6502 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion Error();\}} (in checked mode only). | 6547 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion Error();\}} (in checked mode only). |
6503 %What about an error message as part of the assert?} | 6548 %What about an error message as part of the assert?} |
6504 | 6549 |
6505 \LMHash{} | 6550 \LMHash{} |
6506 It is a static type warning if the type of $e$ may not be assigned to either \ code{bool} or $() \rightarrow$ \code{bool}. | 6551 It is a static type warning if the type of $e$ may not be assigned to either \ code{bool} or $() \rightarrow$ \code{bool}. |
6507 | 6552 |
6508 \rationale{Why is this a statement, not a built in function call? Because it is handled magically so it has no effect and no overhead in production mode. Also, in the absence of final methods. one could not prevent it being overridden (thou gh there is no real harm in that). It cannot be viewed as a function call that is being optimized away because the argument might have side effects. | 6553 \rationale{Why is this a statement, not a built in function call? Because it is handled magically so it has no effect and no overhead in production mode. Also, in the absence of final methods. one could not prevent it being overridden (thou gh there is no real harm in that). It cannot be viewed as a function call that is being optimized away because the argument might have side effects. |
6509 } | 6554 } |
6510 | 6555 |
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7901 | 7946 |
7902 The invariant that each normative paragraph is associated with a line | 7947 The invariant that each normative paragraph is associated with a line |
7903 containing the text \LMHash{} should be maintained. Extra occurrences | 7948 containing the text \LMHash{} should be maintained. Extra occurrences |
7904 of \LMHash{} can be added if needed, e.g., in order to make | 7949 of \LMHash{} can be added if needed, e.g., in order to make |
7905 individual \item{}s in itemized lists addressable. Each \LM.. command | 7950 individual \item{}s in itemized lists addressable. Each \LM.. command |
7906 must occur on a separate line. \LMHash{} must occur immediately | 7951 must occur on a separate line. \LMHash{} must occur immediately |
7907 before the associated paragraph, and \LMLabel must occur immediately | 7952 before the associated paragraph, and \LMLabel must occur immediately |
7908 after the associated \section{}, \subsection{} etc. | 7953 after the associated \section{}, \subsection{} etc. |
7909 | 7954 |
7910 ---------------------------------------------------------------------- | 7955 ---------------------------------------------------------------------- |
OLD | NEW |