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 \usepackage[T1]{fontenc} | 8 \usepackage[T1]{fontenc} |
9 \newcommand{\code}[1]{{\sf #1}} | 9 \newcommand{\code}[1]{{\sf #1}} |
10 \title{Dart Programming Language Specification \\ | 10 \title{Dart Programming Language Specification \\ |
11 {4th edition draft}\\ | 11 {4th edition draft}\\ |
12 {\large Version 1.14}} | 12 {\large Version 1.15.0}} |
13 | 13 |
14 % For information about Location Markers (and in particular the | 14 % For information about Location Markers (and in particular the |
15 % commands \LMHash and \LMLabel), see the long comment at the | 15 % commands \LMHash and \LMLabel), see the long comment at the |
16 % end of this file. | 16 % end of this file. |
17 | 17 |
18 \begin{document} | 18 \begin{document} |
19 \maketitle | 19 \maketitle |
20 \tableofcontents | 20 \tableofcontents |
21 | 21 |
22 | 22 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 $x$ $op$ $y$ is equivalent to the method invocation $x.op^\prime(y)$, assuming
the class of $x$ actually declared a non-operator method named $op^\prime$ defin
ing the same function as the operator $op$. | 132 $x$ $op$ $y$ is equivalent to the method invocation $x.op^\prime(y)$, assuming
the class of $x$ actually declared a non-operator method named $op^\prime$ defin
ing the same function as the operator $op$. |
133 \end{itemize} | 133 \end{itemize} |
134 | 134 |
135 \rationale{This circumlocution is required because x.op(y), where op is an oper
ator, is not legal syntax. However, it is painfully verbose, and we prefer to st
ate this rule once here, and use a concise and clear notation across the specifi
cation. | 135 \rationale{This circumlocution is required because x.op(y), where op is an oper
ator, is not legal syntax. However, it is painfully verbose, and we prefer to st
ate this rule once here, and use a concise and clear notation across the specifi
cation. |
136 } | 136 } |
137 | 137 |
138 \LMHash{} | 138 \LMHash{} |
139 When the specification refers to the order given in the program, it means the or
der of the program source code text, scanning left-to-right and top-to-bottom. | 139 When the specification refers to the order given in the program, it means the or
der of the program source code text, scanning left-to-right and top-to-bottom. |
140 | 140 |
141 \LMHash{} | 141 \LMHash{} |
| 142 When the specification refers to a {\em fresh variable}, it means a variable wit
h a name that doesn't occur anywhere in the current program. |
| 143 When the specification introduces a fresh variable bound to a value, the fresh v
ariable is implicitly bound in a surrounding scope. |
| 144 |
| 145 \LMHash{} |
142 References to otherwise unspecified names of program entities (such as classes o
r functions) are interpreted as the names of members of the Dart core library. | 146 References to otherwise unspecified names of program entities (such as classes o
r functions) are interpreted as the names of members of the Dart core library. |
143 | 147 |
144 \commentary{ | 148 \commentary{ |
145 Examples would be the classes \code{Object} and \code{Type} representing the roo
t of the class hierarchy and the reification of runtime types respectively. | 149 Examples would be the classes \code{Object} and \code{Type} representing the roo
t of the class hierarchy and the reification of runtime types respectively. |
146 } | 150 } |
147 | 151 |
148 \section{Overview} | 152 \section{Overview} |
149 \LMLabel{overview} | 153 \LMLabel{overview} |
150 | 154 |
151 \LMHash{} | 155 \LMHash{} |
152 Dart is a class-based, single-inheritance, pure object-oriented programming lang
uage. Dart is optionally typed (\ref{types}) and supports reified generics. The
run-time type of every object is represented as an instance of class \code{Type}
which can be obtained by calling the getter \code{runtimeType} declared in cl
ass \code{Object}, the root of the Dart class hierarchy. | 156 Dart is a class-based, single-inheritance, pure object-oriented programming lang
uage. Dart is optionally typed (\ref{types}) and supports reified generics. The
run-time type of every object is represented as an instance of class \code{Type}
which can be obtained by calling the getter \code{runtimeType} declared in cl
ass \code{Object}, the root of the Dart class hierarchy. |
153 | 157 |
154 \LMHash{} | 158 \LMHash{} |
155 Dart programs may be statically checked. The static checker will report some vio
lations of the type rules, but such violations do not abort compilation or precl
ude execution. | 159 Dart programs may be statically checked. The static checker will report some vio
lations of the type rules, but such violations do not abort compilation or precl
ude execution. |
156 | 160 |
157 \LMHash{} | 161 \LMHash{} |
158 Dart programs may be executed in one of two modes: production mode or checked mo
de. In production mode, static type annotations (\ref{staticTypes}) have absolut
ely no effect on execution with the exception of reflection and structural type
tests. | 162 Dart programs may be executed in one of two modes: production mode or checked mo
de. In production mode, static type annotations (\ref{staticTypes}) have absolut
ely no effect on execution with the exception of reflection and structural type
tests. |
159 | 163 |
160 \commentary{ | 164 \commentary{ |
161 Reflection, by definition, examines the program structure. If we provide reflect
ive access to the type of a declaration, or to source code, it will inevitably p
roduce results that depend on the types used in the underlying code. | 165 Reflection, by definition, examines the program structure. If we provide reflect
ive access to the type of a declaration, or to source code, it will inevitably p
roduce results that depend on the types used in the underlying code. |
162 | 166 |
163 Type tests also examine the types in a program explicitly. Nevertheless, in most
cases, these will not depend on type annotations. The exceptions to this rule a
re type tests involving function types. Function types are structural, and so de
pend on the types declared for their parameters and on their return types. | 167 Type tests also examine the types in a program explicitly. Nevertheless, in most
cases, these will not depend on type annotations. The exceptions to this rule a
re type tests involving function types. Function types are structural, and so de
pend on the types declared for their parameters and on their return types. |
164 } | 168 } |
165 | 169 |
166 \LMHash{} | 170 \LMHash{} |
167 In checked mode, assignments are dynamically checked, and certain violations of
the type system raise exceptions at run time. | 171 In checked mode, assignments are dynamically checked, and certain violations of
the type system throw exceptions at run time. |
168 | 172 |
169 \commentary{ | 173 \commentary{ |
170 The coexistence between optional typing and reification is based on the followin
g: | 174 The coexistence between optional typing and reification is based on the followin
g: |
171 \begin{enumerate} | 175 \begin{enumerate} |
172 \item Reified type information reflects the types of objects at runtime and may
always be queried by dynamic typechecking constructs (the analogs of instanceOf,
casts, typecase etc. in other languages). Reified type information includes cla
ss declarations, the runtime type (aka class) of an object, and type arguments t
o constructors. | 176 \item Reified type information reflects the types of objects at runtime and may
always be queried by dynamic typechecking constructs (the analogs of instanceOf,
casts, typecase etc. in other languages). Reified type information includes cla
ss declarations, the runtime type (aka class) of an object, and type arguments t
o constructors. |
173 \item Static type annotations determine the types of variables and function decl
arations (including methods and constructors). | 177 \item Static type annotations determine the types of variables and function decl
arations (including methods and constructors). |
174 \item Production mode respects optional typing. Static type annotations do not a
ffect runtime behavior. | 178 \item Production mode respects optional typing. Static type annotations do not a
ffect runtime behavior. |
175 \item Checked mode utilizes static type annotations and dynamic type information
aggressively yet selectively to provide early error detection during developmen
t. | 179 \item Checked mode utilizes static type annotations and dynamic type information
aggressively yet selectively to provide early error detection during developmen
t. |
176 \end{enumerate} | 180 \end{enumerate} |
177 } | 181 } |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 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. | 322 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. |
319 } | 323 } |
320 | 324 |
321 \LMHash{} | 325 \LMHash{} |
322 {\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. | 326 {\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. |
323 | 327 |
324 \LMHash{} | 328 \LMHash{} |
325 {\em Dynamic type errors} are type errors reported in checked mode. | 329 {\em Dynamic type errors} are type errors reported in checked mode. |
326 | 330 |
327 \LMHash{} | 331 \LMHash{} |
328 {\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. | 332 {\em Run-time errors} are exceptions thrown during execution. Whenever we say th
at an exception $ex$ is {\em thrown}, it acts like an expression had {\em thrown
} (\ref{completion}) with $ex$ as exception object and with a stack trace corres
ponding to the current system state. When we say that {\em a} $C$ {\em is thrown
}, where $C$ is a class, we mean that an instance of class $C$ is thrown. |
329 | 333 |
330 \LMHash{} | 334 \LMHash{} |
331 If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately
suspended. | 335 If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately
suspended. |
332 | 336 |
333 | |
334 \section{Variables} | 337 \section{Variables} |
335 \LMLabel{variables} | 338 \LMLabel{variables} |
336 | 339 |
337 \LMHash{} | 340 \LMHash{} |
338 Variables are storage locations in memory. | 341 Variables are storage locations in memory. |
339 | 342 |
340 \begin{grammar} | 343 \begin{grammar} |
341 {\bf variableDeclaration:} | 344 {\bf variableDeclaration:} |
342 declaredIdentifier (`,' identifier)* | 345 declaredIdentifier (`,' identifier)* |
343 . | 346 . |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 | 811 |
809 \rationale{ | 812 \rationale{ |
810 External functions allow us to introduce type information for code that is not
statically known to the Dart compiler. | 813 External functions allow us to introduce type information for code that is not
statically known to the Dart compiler. |
811 } | 814 } |
812 | 815 |
813 \commentary{ | 816 \commentary{ |
814 Examples of external functions might be foreign functions (defined in C, or Java
script etc.), primitives of the implementation (as defined by the Dart runtime),
or code that was dynamically generated but whose interface is statically known.
However, an abstract method is different from an external function, as it has {
\em no} body. | 817 Examples of external functions might be foreign functions (defined in C, or Java
script etc.), primitives of the implementation (as defined by the Dart runtime),
or code that was dynamically generated but whose interface is statically known.
However, an abstract method is different from an external function, as it has {
\em no} body. |
815 } | 818 } |
816 | 819 |
817 \LMHash{} | 820 \LMHash{} |
818 An external function is connected to its body by an implementation specific mech
anism. Attempting to invoke an external function that has not been connected to
its body will raise a \code{NoSuchMethodError} or some subclass thereof. | 821 An external function is connected to its body by an implementation specific mech
anism. Attempting to invoke an external function that has not been connected to
its body will throw a \code{NoSuchMethodError} or some subclass thereof. |
819 | 822 |
820 \LMHash{} | 823 \LMHash{} |
821 The actual syntax is given in sections \ref{classes} and \ref{librariesAndScript
s} below. | 824 The actual syntax is given in sections \ref{classes} and \ref{librariesAndScript
s} below. |
822 | 825 |
823 \section{Classes} | 826 \section{Classes} |
824 \LMLabel{classes} | 827 \LMLabel{classes} |
825 | 828 |
826 \LMHash{} | 829 \LMHash{} |
827 A {\em class} defines the form and behavior of a set of objects which are its {\
em instances}. Classes may be defined by class declarations as described below,
or via mixin applications (\ref{mixinApplication}). | 830 A {\em class} defines the form and behavior of a set of objects which are its {\
em instances}. Classes may be defined by class declarations as described below,
or via mixin applications (\ref{mixinApplication}). |
828 | 831 |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 | 1208 |
1206 %whose execution sets the value of $v$ to the incoming argument $x$. | 1209 %whose execution sets the value of $v$ to the incoming argument $x$. |
1207 | 1210 |
1208 % It is a compile-time error/warning if a class $C$ declares a final instance va
riable $v$ and $C$ inherits a setter $v=$. | 1211 % It is a compile-time error/warning if a class $C$ declares a final instance va
riable $v$ and $C$ inherits a setter $v=$. |
1209 | 1212 |
1210 | 1213 |
1211 \subsection{Constructors} | 1214 \subsection{Constructors} |
1212 \LMLabel{constructors} | 1215 \LMLabel{constructors} |
1213 | 1216 |
1214 \LMHash{} | 1217 \LMHash{} |
1215 A {\em constructor} is a special function that is used in instance creation expr
essions (\ref{instanceCreation}) to produce objects. Constructors may be generat
ive (\ref{generativeConstructors}) or they may be factories (\ref{factories}). | 1218 A {\em constructor} is a special function that is used in instance creation expr
essions (\ref{instanceCreation}) to obtain objects, typically by creating or ini
tializing them. |
| 1219 Constructors may be generative (\ref{generativeConstructors}) or they may be fac
tories (\ref{factories}). |
1216 | 1220 |
1217 \LMHash{} | 1221 \LMHash{} |
1218 A {\em constructor name} always begins with the name of its immediately enclosin
g class, and may optionally be followed by a dot and an identifier $id$. It is a
compile-time error if $id$ is the name of a member declared in the immediately
enclosing class. It is a compile-time error if the name of a constructor is no
t a constructor name. | 1222 A {\em constructor name} always begins with the name of its immediately enclosin
g class, and may optionally be followed by a dot and an identifier $id$. It is a
compile-time error if $id$ is the name of a member declared in the immediately
enclosing class. It is a compile-time error if the name of a constructor is no
t a constructor name. |
1219 | 1223 |
1220 | 1224 |
1221 % In what scope do constructors go? The simple names of named constructors go i
n the static scope of the class. Unnamed ones go nowhere, but we use the class n
ame to refer to them; the class name could also in the static scope of the class
as well to prevent weird errors, or we could ban it explicitly and avoiding dup
lication. Similarly, the instance scope could contain the constructor names and
class name, or we could have special rules to prevent collisions between instanc
e members and constructors or the class. | 1225 % In what scope do constructors go? The simple names of named constructors go i
n the static scope of the class. Unnamed ones go nowhere, but we use the class n
ame to refer to them; the class name could also in the static scope of the class
as well to prevent weird errors, or we could ban it explicitly and avoiding dup
lication. Similarly, the instance scope could contain the constructor names and
class name, or we could have special rules to prevent collisions between instanc
e members and constructors or the class. |
1222 | 1226 |
1223 % The enclosing scope of a generative constructor is the instance scope of the c
lass in which it is declared (but what about redirecting?) | 1227 % The enclosing scope of a generative constructor is the instance scope of the c
lass in which it is declared (but what about redirecting?) |
1224 | 1228 |
1225 \LMHash{} | 1229 \LMHash{} |
1226 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}. | 1230 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}. |
1227 | 1231 |
1228 \subsubsection{Generative Constructors} | 1232 \subsubsection{Generative Constructors} |
1229 \LMLabel{generativeConstructors} | 1233 \LMLabel{generativeConstructors} |
1230 | 1234 |
1231 \LMHash{} | 1235 \LMHash{} |
1232 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. | 1236 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 optional
body. |
1233 | 1237 |
1234 \begin{grammar} | 1238 \begin{grammar} |
1235 {\bf constructorSignature:} | 1239 {\bf constructorSignature:} |
1236 identifier (`{\escapegrammar .}' identifier)? formalParameterList | 1240 identifier (`{\escapegrammar .}' identifier)? formalParameterList |
1237 . | 1241 . |
1238 \end{grammar} | 1242 \end{grammar} |
1239 | 1243 |
1240 \LMHash{} | 1244 \LMHash{} |
1241 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 $id$ is the name of an
instance variable of the immediately enclosing class. It is a compile-time erro
r if $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 other than
a non-redirecting generative constructor. | 1245 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 $id$ is the name of an
instance variable of the immediately enclosing class. It is a compile-time erro
r if $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 other than
a non-redirecting generative constructor. |
1242 | 1246 |
1243 \LMHash{} | 1247 \LMHash{} |
1244 If an explicit type is attached to the initializing formal, that is its static t
ype. Otherwise, the type of an initializing formal named $id$ is $T_{id}$, where
$T_{id}$ is the type of the field named $id$ in the immediately enclosing class
. It is a static warning if the static type of $id$ is not assignable to $T_{id}
$. | 1248 If an explicit type is attached to the initializing formal, that is its static t
ype. Otherwise, the type of an initializing formal named $id$ is $T_{id}$, where
$T_{id}$ is the type of the field named $id$ in the immediately enclosing class
. It is a static warning if the static type of $id$ is not assignable to $T_{id}
$. |
1245 | 1249 |
1246 \LMHash{} | 1250 \LMHash{} |
1247 Initializing formals constitute an exception to the rule that every formal param
eter introduces a local variable into the formal parameter scope (\ref{formalPar
ameters}). | 1251 Initializing formals constitute an exception to the rule that every formal param
eter introduces a local variable into the formal parameter scope (\ref{formalPar
ameters}). |
1248 When the formal parameter list of a non-redirecting generative constructor conta
ins any initializing formals, a new scope is introduced, the {\em formal paramet
er initializer scope}, which is the current scope of the initializer list of the
constructor, and which is enclosed in the scope where the constructor is declar
ed. | 1252 When the formal parameter list of a non-redirecting generative constructor conta
ins any initializing formals, a new scope is introduced, the {\em formal paramet
er initializer scope}, which is the current scope of the initializer list of the
constructor, and which is enclosed in the scope where the constructor is declar
ed. |
1249 Each initializing formal in the formal parameter list introduces a final local v
ariable into the formal parameter initializer scope, but not into the formal par
ameter scope; every other formal parameter introduces a local variable into both
the formal parameter scope and the formal parameter initializer scope. | 1253 Each initializing formal in the formal parameter list introduces a final local v
ariable into the formal parameter initializer scope, but not into the formal par
ameter scope; every other formal parameter introduces a local variable into both
the formal parameter scope and the formal parameter initializer scope. |
1250 | 1254 |
1251 \commentary{ | 1255 \commentary{ |
1252 This means that formal parameters, including initializing formals, must have dis
tinct names, and that initializing formals are in scope for the initializer list
, but they are not in scope for the body of the constructor. | 1256 This means that formal parameters, including initializing formals, must have dis
tinct names, and that initializing formals are in scope for the initializer list
, but they are not in scope for the body of the constructor. |
1253 When a formal parameter introduces a local variable into two scopes, it is still
one variable and hence one storage location. | 1257 When a formal parameter introduces a local variable into two scopes, it is still
one variable and hence one storage location. |
1254 The type of the constructor is defined in terms of its formal parameters, includ
ing the initializing formals. | 1258 The type of the constructor is defined in terms of its formal parameters, includ
ing the initializing formals. |
1255 } | 1259 } |
1256 | 1260 |
1257 \LMHash{} | 1261 \LMHash{} |
1258 Initializing formals are executed during the execution of generative constructor
s detailed below. Executing an initializing formal \code{\THIS{}.id} causes the
field \code{id} of the immediately surrounding class to be assigned the value o
f the corresponding actual parameter, unless $id$ is a final variable that has a
lready been initialized, in which case a runtime error occurs. | 1262 Initializing formals are executed during the execution of generative constructor
s detailed below. Executing an initializing formal \code{\THIS{}.$id$} causes t
he field $id$ of the immediately surrounding class to be assigned the value of t
he corresponding actual parameter, unless $id$ is a final variable that has alre
ady been initialized, in which case a runtime error occurs. |
1259 | 1263 |
1260 | 1264 |
1261 \commentary{ | 1265 \commentary{ |
1262 The above rule allows initializing formals to be used as optional parameters: | 1266 The above rule allows initializing formals to be used as optional parameters: |
1263 } | 1267 } |
1264 | 1268 |
1265 \begin{dartCode} | 1269 \begin{dartCode} |
1266 class A \{ | 1270 class A \{ |
1267 int x; | 1271 int x; |
1268 A([this.x]); | 1272 A([this.x]); |
(...skipping 25 matching lines...) Expand all Loading... |
1294 | 1298 |
1295 \LMHash{} | 1299 \LMHash{} |
1296 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. | 1300 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. |
1297 | 1301 |
1298 \begin{grammar} | 1302 \begin{grammar} |
1299 {\bf redirection:} | 1303 {\bf redirection:} |
1300 `{\escapegrammar :}' \THIS{} (`{\escapegrammar .}' identifier)? arguments | 1304 `{\escapegrammar :}' \THIS{} (`{\escapegrammar .}' identifier)? arguments |
1301 . | 1305 . |
1302 \end{grammar} | 1306 \end{grammar} |
1303 | 1307 |
1304 % Need to specify exactly how executing a redirecting constructor works | |
1305 | |
1306 | |
1307 %\Q{We now have generative constructors with no bodies as well.} | 1308 %\Q{We now have generative constructors with no bodies as well.} |
1308 | 1309 |
1309 \paragraph{Initializer Lists} | 1310 \paragraph{Initializer Lists} |
1310 \LMLabel{initializerLists} | 1311 \LMLabel{initializerLists} |
1311 | 1312 |
1312 \LMHash{} | 1313 \LMHash{} |
1313 An initializer list begins with a colon, and consists of a comma-separated list
of individual {\em initializers}. There are two kinds of initializers. | 1314 An initializer list begins with a colon, and consists of a comma-separated list
of individual {\em initializers}. There are two kinds of initializers. |
1314 \begin{itemize} | 1315 \begin{itemize} |
1315 \item A {\em superinitializer} identifies a {\em superconstructor} - that is, a
specific constructor of the superclass. Execution of the superinitializer caus
es the initializer list of the superconstructor to be executed. | 1316 \item A {\em superinitializer} identifies a {\em superconstructor} - that is, a
specific constructor of the superclass. Execution of the superinitializer cause
s the initializer list of the superconstructor to be executed. |
1316 | 1317 |
1317 \item An {\em instance variable initializer} assigns a value to an individual in
stance variable. | 1318 \item An {\em instance variable initializer} assigns a value to an individual in
stance variable. |
1318 \end{itemize} | 1319 \end{itemize} |
1319 | 1320 |
1320 \begin{grammar} | 1321 \begin{grammar} |
1321 {\bf initializers:} | 1322 {\bf initializers:} |
1322 `{\escapegrammar :}' superCallOrFieldInitializer (`,' superCallOrFieldInit
ializer)* | 1323 `{\escapegrammar :}' superCallOrFieldInitializer (`,' superCallOrFieldInit
ializer)* |
1323 . | 1324 . |
1324 | 1325 |
1325 | 1326 |
1326 {\bf superCallOrFieldInitializer:}\SUPER{} arguments; | 1327 {\bf superCallOrFieldInitializer:}\SUPER{} arguments; |
1327 \SUPER{} `{\escapegrammar .}' identifier arguments; | 1328 \SUPER{} `{\escapegrammar .}' identifier arguments; |
1328 fieldInitializer | 1329 fieldInitializer |
1329 . | 1330 . |
1330 | 1331 |
1331 {\bf fieldInitializer:} | 1332 {\bf fieldInitializer:} |
1332 (\THIS{} `{\escapegrammar .}')? identifier `=' conditionalExpression casca
deSection* | 1333 (\THIS{} `{\escapegrammar .}')? identifier `=' conditionalExpression casca
deSection* |
1333 . | 1334 . |
1334 | 1335 |
1335 \end{grammar} | 1336 \end{grammar} |
1336 | 1337 |
1337 \LMHash{} | 1338 \LMHash{} |
1338 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. | 1339 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. |
1339 | 1340 |
1340 \LMHash{} | 1341 \LMHash{} |
1341 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: | 1342 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: |
1342 \begin{itemize} | 1343 \begin{itemize} |
1343 \item Initialization at the declaration of $f$. | 1344 \item Initialization at the declaration of $f$. |
1344 \item Initialization by means of an initializing formal of $k$. | 1345 \item Initialization by means of an initializing formal of $k$. |
1345 \end{itemize} | 1346 \end{itemize} |
1346 | 1347 |
1347 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. | 1348 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. |
1348 | 1349 |
1349 | 1350 |
1350 \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. | 1351 \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. |
1351 } | 1352 } |
1352 | 1353 |
1353 \LMHash{} | 1354 \LMHash{} |
1354 It is a compile-time error if a generative constructor of class \code{Object}
includes a superinitializer. | 1355 It is a compile-time error if a generative constructor of class \code{Object} in
cludes a superinitializer. |
1355 | 1356 |
1356 \LMHash{} | 1357 \LMHash{} |
1357 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$. | 1358 Execution of a generative constructor $k$ of type $T$ to initialize a fresh inst
ance $i$ |
| 1359 is always done with respect to a set of bindings for its formal parameters |
| 1360 and the type parameters of the immediately enclosing class bound to a set of act
ual type arguments of $T$, $V_1, \ldots , V_m$. |
1358 | 1361 |
1359 \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,. | 1362 \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. |
1360 } | 1363 } |
1361 | 1364 |
1362 \LMHash{} | 1365 \LMHash{} |
1363 If $k$ is redirecting then its redirect clause has the form | 1366 If $k$ is redirecting then its redirect clause has the form |
1364 | 1367 |
1365 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ | 1368 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
1366 | 1369 |
1367 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$. | 1370 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$. |
1368 | 1371 |
1369 \LMHash{} | 1372 \LMHash{} |
1370 Otherwise, execution proceeds as follows: | 1373 Otherwise, execution proceeds as follows: |
1371 | 1374 |
1372 \LMHash{} | 1375 \LMHash{} |
1373 %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). | 1376 The instance variable declarations of the immediately enclosing class are visite
d in the order they appear in the program text. |
1374 %Next, a | 1377 For each such declaration $d$, if $d$ has the form \code{$finalConstVarOrType$ $
v$ = $e$; } |
| 1378 then $e$ is evaluated to an object $o$ |
| 1379 and the instance variable $v$ of $i$ is bound to $o$. |
| 1380 |
| 1381 \LMHash{} |
1375 Any initializing formals declared in $k$'s parameter list are executed in the or
der they appear in the program text. | 1382 Any initializing formals declared in $k$'s parameter list are executed in the or
der they appear in the program text. |
1376 % In fact, this order is unobservable; this could be done any time prior to runn
ing the body, since | 1383 % In fact, this order is unobservable; this could be done any time prior to runn
ing the body, since |
1377 % these only effect \THIS{}. | 1384 % these only effect \THIS{}. |
1378 Then, $k$'s initializers are executed in the order they appear in the program. | 1385 Then, the initializers of $k$'s initializer list are executed to initialize $i$ |
| 1386 in the order they appear in the program. |
1379 | 1387 |
1380 \rationale {We could observe the order by side effecting external routines call
ed. So we need to specify the order.} | 1388 \rationale {We could observe the order by side effecting external routines calle
d. So we need to specify the order.} |
1381 | 1389 |
1382 \LMHash{} | 1390 \LMHash{} |
1383 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$. | 1391 Then if any instance variable of $i$ declared by the immediately enclosing class |
| 1392 is not yet bound to a value, |
| 1393 it is a dynamic error if such a variable is a \FINAL{} variable, |
| 1394 otherwise all such variables are initialized with the \NULL{} value. |
1384 | 1395 |
1385 \rationale{ | 1396 \LMHash{} |
1386 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. | 1397 Then, unless the enclosing class is \code{Object}, the explicitly specified or |
| 1398 implicitly added superinitializer (\ref{initializerLists}) is executed to |
| 1399 further initialize $i$. |
| 1400 |
| 1401 \commentary{ |
| 1402 The super constructor call can be written anywhere |
| 1403 in the initializer list of $k$, |
| 1404 but the actual call always happens after all initializers have been processed. |
| 1405 It is not equivalent to moving the super call to the end of the initializer list |
| 1406 because the argument expressions may have visible side effects |
| 1407 which must happen in the order the expressions occur in the program text. |
1387 } | 1408 } |
1388 | 1409 |
1389 \LMHash{} | 1410 \LMHash{} |
1390 Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} proceeds as fol
lows: | 1411 After the superinitializer has completed, the body of $k$ is executed in a scope
where \THIS{} is bound to $i$. |
| 1412 |
| 1413 \rationale{ |
| 1414 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 b
eing invoked in the initializer. |
| 1415 } |
1391 | 1416 |
1392 \LMHash{} | 1417 \LMHash{} |
1393 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$. | 1418 During the execution of a generative constructor to initialize an instance $i$, |
| 1419 execution of an initializer of the form \code{\THIS{}.$v$ = $e$} |
| 1420 proceeds as follows: |
1394 | 1421 |
1395 \LMHash{} | 1422 \LMHash{} |
1396 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t
he form \code{\THIS{}.$v$ = $e$}. | 1423 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$. |
| 1424 |
| 1425 \LMHash{} |
| 1426 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t
he form \code{\THIS{}.$v$ = $e$}. |
1397 | 1427 |
1398 \LMHash{} | 1428 \LMHash{} |
1399 Execution of a superinitializer of the form | 1429 Execution of a superinitializer of the form |
1400 | 1430 |
1401 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ | 1431 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ |
1402 | 1432 |
1403 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}:
a_{n+k})$ | 1433 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}:
a_{n+k})$ |
1404 | 1434 |
1405 proceeds as follows: | 1435 proceeds as follows: |
1406 | 1436 |
1407 \LMHash{} | 1437 \LMHash{} |
1408 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}:
a_{n+k})$ is evaluated. | 1438 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}:
a_{n+k})$ is evaluated. |
1409 | 1439 |
1410 \LMHash{} | 1440 \LMHash{} |
1411 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$. | 1441 Then, after the remainder of the initializer list of $k$ has been executed, |
| 1442 the superconstructor is executed as follows: |
1412 | 1443 |
1413 \LMHash{} | 1444 \LMHash{} |
1414 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$. | 1445 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$ be
the actual type arguments passed to $S$ in the superclass clause of $C$. |
| 1446 |
| 1447 \LMHash{} |
| 1448 The generative constructor $S$ (respectively $S.id$) of $S$ is executed |
| 1449 to initialize $i$ with respect to the bindings that resulted from the evaluation
of |
| 1450 $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
| 1451 and the type parameters (if any) of class $S$ bound to $U_1, \ldots, U_m$. |
1415 | 1452 |
1416 \LMHash{} | 1453 \LMHash{} |
1417 It is a compile-time error if class $S$ does not declare a generative constructo
r named $S$ (respectively $S.id$). | 1454 It is a compile-time error if class $S$ does not declare a generative constructo
r named $S$ (respectively $S.id$). |
1418 | 1455 |
1419 \subsubsection{Factories} | 1456 \subsubsection{Factories} |
1420 \LMLabel{factories} | 1457 \LMLabel{factories} |
1421 | 1458 |
1422 \LMHash{} | 1459 \LMHash{} |
1423 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden
tifierReference}) \FACTORY{}. | 1460 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden
tifierReference}) \FACTORY{}. |
1424 | 1461 |
(...skipping 12 matching lines...) Expand all Loading... |
1437 \LMHash{} | 1474 \LMHash{} |
1438 It is a compile-time error if $M$ is not the name of the immediately enclosing c
lass. | 1475 It is a compile-time error if $M$ is not the name of the immediately enclosing c
lass. |
1439 | 1476 |
1440 \LMHash{} | 1477 \LMHash{} |
1441 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. | 1478 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. |
1442 | 1479 |
1443 \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.} | 1480 \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.} |
1444 | 1481 |
1445 \rationale{Factories address classic weaknesses associated with constructors in
other languages. | 1482 \rationale{Factories address classic weaknesses associated with constructors in
other languages. |
1446 Factories can produce instances that are not freshly allocated: they can come fr
om a cache. Likewise, factories can return instances of different classes. | 1483 Factories can produce instances that are not freshly allocated: they can come fr
om a cache. Likewise, factories can return instances of different classes. |
1447 | |
1448 } | 1484 } |
1449 | 1485 |
1450 \paragraph{Redirecting Factory Constructors} | 1486 \paragraph{Redirecting Factory Constructors} |
1451 \LMLabel{redirectingFactoryConstructors} | 1487 \LMLabel{redirectingFactoryConstructors} |
1452 | 1488 |
1453 \LMHash{} | 1489 \LMHash{} |
1454 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. | 1490 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. |
1455 | 1491 |
1456 \begin{grammar} | 1492 \begin{grammar} |
1457 {\bf redirectingFactoryConstructorSignature:} | 1493 {\bf redirectingFactoryConstructorSignature:} |
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2345 Metadata can appear before a library, part header, class, typedef, type paramete
r, constructor, factory, function, field, parameter, or variable declaration and
before an import, export or part directive. | 2381 Metadata can appear before a library, part header, class, typedef, type paramete
r, constructor, factory, function, field, parameter, or variable declaration and
before an import, export or part directive. |
2346 | 2382 |
2347 \LMHash{} | 2383 \LMHash{} |
2348 The constant expression given in an annotation is type checked and evaluated in
the scope surrounding the declaration being annotated. | 2384 The constant expression given in an annotation is type checked and evaluated in
the scope surrounding the declaration being annotated. |
2349 | 2385 |
2350 | 2386 |
2351 \section{Expressions} | 2387 \section{Expressions} |
2352 \LMLabel{expressions} | 2388 \LMLabel{expressions} |
2353 | 2389 |
2354 \LMHash{} | 2390 \LMHash{} |
2355 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}). | 2391 \label{evaluation} |
| 2392 An {\em expression} is a fragment of Dart code that can be evaluated at run time
. |
| 2393 Evaluating an expression either {\em produces a value} (an object), |
| 2394 or it {\em throws} an exception object and an associated stack trace. |
| 2395 In the former case, we also say that the expression {\em evaluates to a value}. |
2356 | 2396 |
| 2397 \LMHash{} |
| 2398 Every expression has an associated static type (\ref{staticTypes}). |
| 2399 Every value has an associated dynamic type (\ref{dynamicTypeSystem}). |
| 2400 |
| 2401 \LMHash{} |
| 2402 If evaluation of one expression, $e$, is defined in terms of evaluation of anoth
er expression, typically a subexpression of $e$, |
| 2403 and the evaluation of the other expression throws an exception and a stack trace
, |
| 2404 the evaluation of $e$ stops at that point and throws the same exception object a
nd stack trace. |
2357 | 2405 |
2358 \begin{grammar} | 2406 \begin{grammar} |
2359 | 2407 |
2360 {\bf expression:}assignableExpression assignmentOperator expression; | 2408 {\bf expression:}assignableExpression assignmentOperator expression; |
2361 conditionalExpression cascadeSection*; | 2409 conditionalExpression cascadeSection*; |
2362 throwExpression | 2410 throwExpression |
2363 . | 2411 . |
2364 | 2412 |
2365 | 2413 |
2366 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio
nWithoutCascade; | 2414 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio
nWithoutCascade; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2465 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $
e_3$ are constant expressions and $e_1$ evaluates to a boolean value. | 2513 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $
e_3$ are constant expressions and $e_1$ evaluates to a boolean value. |
2466 \item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are co
nstant expressions. | 2514 \item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are co
nstant expressions. |
2467 \item An expression of the form \code{$e$.length} where $e$ is a constant expres
sion that evaluates to a string value. | 2515 \item An expression of the form \code{$e$.length} where $e$ is a constant expres
sion that evaluates to a string value. |
2468 \end{itemize} | 2516 \end{itemize} |
2469 | 2517 |
2470 % null in all the expressions | 2518 % null in all the expressions |
2471 | 2519 |
2472 % designed so constants do not depend on check diode being on or not. | 2520 % designed so constants do not depend on check diode being on or not. |
2473 | 2521 |
2474 \LMHash{} | 2522 \LMHash{} |
2475 It is a compile-time error if an expression is required to be a constant express
ion but its evaluation would raise an exception. | 2523 It is a compile-time error if an expression is required to be a constant express
ion but its evaluation would throw an exception. |
2476 | 2524 |
2477 % so, checked mode? analyzers? editor/development compilers? | 2525 % so, checked mode? analyzers? editor/development compilers? |
2478 \commentary{ | 2526 \commentary{ |
2479 Note that there is no requirement that every constant expression evaluate correc
tly. Only when a constant expression is required (e.g., to initialize a constant
variable, or as a default value of a formal parameter, or as metadata) do we in
sist that a constant expression actually be evaluated successfully at compile ti
me. | 2527 Note that there is no requirement that every constant expression evaluate correc
tly. Only when a constant expression is required (e.g., to initialize a constant
variable, or as a default value of a formal parameter, or as metadata) do we in
sist that a constant expression actually be evaluated successfully at compile ti
me. |
2480 | 2528 |
2481 The above is not dependent on program control-flow. The mere presence of a requi
red compile time constant whose evaluation would fail within a program is an err
or. This also holds recursively: since compound constants are composed out of c
onstants, if any subpart of a constant would raise an exception when evaluated,
that is an error. | 2529 The above is not dependent on program control-flow. The mere presence of a requi
red compile time constant whose evaluation would fail within a program is an err
or. This also holds recursively: since compound constants are composed out of c
onstants, if any subpart of a constant would throw an exception when evaluated,
that is an error. |
2482 | 2530 |
2483 On the other hand, since implementations are free to compile code late, some com
pile-time errors may manifest quite late. | 2531 On the other hand, since implementations are free to compile code late, some com
pile-time errors may manifest quite late. |
2484 } | 2532 } |
2485 | 2533 |
2486 \begin{dartCode} | 2534 \begin{dartCode} |
2487 \CONST{} x = 1 ~/ 0; | 2535 \CONST{} x = 1 ~/ 0; |
2488 \FINAL{} y = 1 ~/ 0; | 2536 \FINAL{} y = 1 ~/ 0; |
2489 | 2537 |
2490 \CLASS{} K \{ | 2538 \CLASS{} K \{ |
2491 m1() \{ | 2539 m1() \{ |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2548 listLiteral | 2596 listLiteral |
2549 . | 2597 . |
2550 \end{grammar} | 2598 \end{grammar} |
2551 | 2599 |
2552 | 2600 |
2553 | 2601 |
2554 \subsection{Null} | 2602 \subsection{Null} |
2555 \LMLabel{null} | 2603 \LMLabel{null} |
2556 | 2604 |
2557 \LMHash{} | 2605 \LMHash{} |
2558 The reserved word \NULL{} denotes the {\em null object}. | 2606 The reserved word \NULL{} evaluates to the {\em null object}. |
2559 %\Q{Any methods, such as \code{isNull}?} | 2607 %\Q{Any methods, such as \code{isNull}?} |
2560 | 2608 |
2561 \begin{grammar} | 2609 \begin{grammar} |
2562 {\bf nullLiteral:} | 2610 {\bf nullLiteral:} |
2563 \NULL{} | 2611 \NULL{} |
2564 . | 2612 . |
2565 \end{grammar} | 2613 \end{grammar} |
2566 | 2614 |
2567 \LMHash{} | 2615 \LMHash{} |
2568 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}. | 2616 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 extend, mix in or implement \code{Null}. |
2569 Invoking a method on \NULL{} yields a \code{NoSuchMethodError} unless the metho
d is explicitly implemented by class \code{Null}. | 2617 The \code{Null} class declares no methods except those also declared by \code{Ob
ject}. |
2570 | 2618 |
2571 \LMHash{} | 2619 \LMHash{} |
2572 The static type of \NULL{} is $\bot$. | 2620 The static type of \NULL{} is $\bot$. |
2573 | 2621 |
2574 \rationale{The decision to use $\bot$ instead of \code{Null} allows \NULL{} to b
e be assigned everywhere without complaint by the static checker. | 2622 \rationale{The decision to use $\bot$ instead of \code{Null} allows \NULL{} to b
e be assigned everywhere without complaint by the static checker. |
2575 } | 2623 } |
2576 | 2624 |
2577 | 2625 |
2578 \subsection{Numbers} | 2626 \subsection{Numbers} |
2579 \LMLabel{numbers} | 2627 \LMLabel{numbers} |
(...skipping 18 matching lines...) Expand all Loading... |
2598 `0X' HEX\_DIGIT+ | 2646 `0X' HEX\_DIGIT+ |
2599 . | 2647 . |
2600 | 2648 |
2601 {\bf HEX\_DIGIT:}`a'{\escapegrammar ..}'f'; | 2649 {\bf HEX\_DIGIT:}`a'{\escapegrammar ..}'f'; |
2602 `A'{\escapegrammar ..}'F'; | 2650 `A'{\escapegrammar ..}'F'; |
2603 DIGIT | 2651 DIGIT |
2604 . | 2652 . |
2605 \end{grammar} | 2653 \end{grammar} |
2606 | 2654 |
2607 \LMHash{} | 2655 \LMHash{} |
2608 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. | 2656 If a numeric literal begins with the prefix `0x' or `0X', |
| 2657 it denotes the integer represented by the hexadecimal numeral |
| 2658 following `0x' (respectively `0X'). |
| 2659 Otherwise, if the numeric literal contains only decimal digits, |
| 2660 it denotes an integer represented as a decimal numeral. |
| 2661 In either case the literal evaluates to an instance of the class \code{int} |
| 2662 with the integer value represented by that numeral. |
| 2663 Otherwise, the numeric literal contains either a decimal point or an exponent pa
rt |
| 2664 and it evaluates to a an instance of the `double` class |
| 2665 representing a 64 bit double precision floating point number |
| 2666 as specified by the IEEE 754 standard. |
2609 | 2667 |
2610 \LMHash{} | 2668 \LMHash{} |
2611 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. | 2669 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. |
2612 | 2670 |
2613 \commentary{ | 2671 \commentary{ |
2614 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. | 2672 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. |
2615 } | 2673 } |
2616 | 2674 |
2617 \LMHash{} | 2675 \LMHash{} |
2618 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}. | 2676 It is a compile-time error for a class to extend, mix in or implement \code{int}
. |
| 2677 It is a compile-time error for a class to extend, mix in or implement \code{doub
le}. |
| 2678 It is a compile-time error for any class other than \code{int} and \code{double}
to extend, mix in or implement \code{num}. |
2619 | 2679 |
2620 \LMHash{} | 2680 \LMHash{} |
2621 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}. | 2681 An {\em integer literal} is either a hexadecimal integer literal or a decimal i
nteger literal. |
| 2682 The static type of an integer literal is \code{int}. |
2622 | 2683 |
2623 \LMHash{} | 2684 \LMHash{} |
2624 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}. | 2685 A {\em literal double} is a numeric literal that is not an integer literal. The
static type of a literal double is \code{double}. |
2625 The static type of a literal double is \code{double}. | |
2626 | 2686 |
2627 \subsection{Booleans} | 2687 \subsection{Booleans} |
2628 \LMLabel{booleans} | 2688 \LMLabel{booleans} |
2629 | 2689 |
2630 \LMHash{} | 2690 \LMHash{} |
2631 The reserved words \TRUE{} and \FALSE{} denote objects that represent the boolea
n values true and false respectively. They are the {\em boolean literals}. | 2691 The reserved words \TRUE{} and \FALSE{} evaluate to objects {\em true} and {\em
false} that represent the boolean values true and false respectively. |
| 2692 They are the {\em boolean literals}. |
2632 | 2693 |
2633 \begin{grammar} | 2694 \begin{grammar} |
2634 {\bf booleanLiteral:}\TRUE{}; | 2695 {\bf booleanLiteral:}\TRUE{}; |
2635 \FALSE{} | 2696 \FALSE{} |
2636 . | 2697 . |
2637 \end{grammar} | 2698 \end{grammar} |
2638 | 2699 |
2639 \LMHash{} | 2700 \LMHash{} |
2640 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}. | 2701 Both {\em true} and {\em false} are instances of the built-in class \code{bool}, |
2641 | 2702 and there are no other objects that implement \code{bool}. |
2642 \commentary{ | 2703 It is a compile-time error for a class to extend, mix in or implement \code{bool
}. |
2643 It follows that the two boolean literals are the only two instances of \code{boo
l}. | |
2644 } | |
2645 | 2704 |
2646 \LMHash{} | 2705 \LMHash{} |
2647 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}. | 2706 Invoking the getter \code{runtimeType} on a boolean value returns the \code{Type
} object that is the value of the expression \code{bool}. The static type of a b
oolean literal is \code{bool}. |
2648 | 2707 |
2649 \subsubsection{Boolean Conversion} | 2708 \subsubsection{Boolean Conversion} |
2650 \LMLabel{booleanConversion} | 2709 \LMLabel{booleanConversion} |
2651 | 2710 |
2652 \LMHash{} | 2711 \LMHash{} |
2653 {\em Boolean conversion} maps any object $o$ into a boolean. Boolean conversion
is defined by the function application | 2712 {\em Boolean conversion} maps any object $o$ into a boolean. Boolean conversion
is defined by the function application |
2654 | 2713 |
2655 \begin{dartCode} | 2714 \begin{dartCode} |
2656 (bool v)\{ | 2715 (bool v)\{ |
2657 \ASSERT{}(v != \NULL{}); | 2716 \ASSERT{}(v != \NULL{}); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2838 stringInterpolation | 2897 stringInterpolation |
2839 . | 2898 . |
2840 | 2899 |
2841 {\bf NEWLINE:}$\backslash$ n; | 2900 {\bf NEWLINE:}$\backslash$ n; |
2842 $\backslash$ r | 2901 $\backslash$ r |
2843 . | 2902 . |
2844 | 2903 |
2845 \end{grammar} | 2904 \end{grammar} |
2846 | 2905 |
2847 \LMHash{} | 2906 \LMHash{} |
2848 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}. | 2907 All string literals evaluate to instances of the built-in class \code{String}. |
| 2908 It is a compile-time error for a class to extend, mix in or implement \code{Stri
ng}. |
| 2909 The static type of a string literal is \code{String}. |
2849 | 2910 |
2850 \subsubsection{String Interpolation} | 2911 \subsubsection{String Interpolation} |
2851 \LMLabel{stringInterpolation} | 2912 \LMLabel{stringInterpolation} |
2852 | 2913 |
2853 \LMHash{} | 2914 \LMHash{} |
2854 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}. | 2915 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}. |
2855 | 2916 |
2856 \begin{grammar} | 2917 \begin{grammar} |
2857 {\bf stringInterpolation:}`\$' IDENTIFIER\_NO\_DOLLAR; | 2918 {\bf stringInterpolation:}`\$' IDENTIFIER\_NO\_DOLLAR; |
2858 `\$' `\{' expression `\}' % could be top level expression, no? | 2919 `\$' `\{' expression `\}' % could be top level expression, no? |
2859 . | 2920 . |
2860 \end{grammar} | 2921 \end{grammar} |
2861 | 2922 |
2862 \commentary{The reader will note that the expression inside the interpolation co
uld itself include strings, which could again be interpolated recursively. | 2923 \commentary{The reader will note that the expression inside the interpolation co
uld itself include strings, which could again be interpolated recursively. |
2863 } | 2924 } |
2864 | 2925 |
2865 \LMHash{} | 2926 \LMHash{} |
2866 An unescaped \$ character in a string signifies the beginning of an interpolated
expression. The \$ sign may be followed by either: | 2927 An unescaped \$ character in a string signifies the beginning of an interpolated
expression. The \$ sign may be followed by either: |
2867 \begin{itemize} | 2928 \begin{itemize} |
2868 \item A single identifier $id$ that must not contain the \$ character. | 2929 \item A single identifier $id$ that must not contain the \$ character. |
2869 \item An expression $e$ delimited by curly braces. | 2930 \item An expression $e$ delimited by curly braces. |
2870 \end{itemize} | 2931 \end{itemize} |
2871 | 2932 |
2872 \LMHash{} | 2933 \LMHash{} |
2873 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$''
}. | 2934 The form \code{\$id} is equivalent to the form \code{\$\{id\}}. |
| 2935 An interpolated string, $s$, with content `\code{$s_0$\$\{$e_1$\}$s_1\ldots{}s_{
n-1}\$\{e_n\}s_{n}$}' (where any of $s_0 \ldots{} s_n$ can be empty) |
| 2936 is evaluated by evaluating each expression $e_i$ ($1 \le i \le n$) in to a strin
g $r_i$ in the order they occur in the source text, as follows: |
| 2937 \begin{itemize} |
| 2938 \item{} Evaluate $e_i$ to an object $o_i$. |
| 2939 \item{} Invoke the \code{toString} method on $o_i$ with no arguments, and let |
| 2940 $r_i$ be the returned value. |
| 2941 \item{} If $r_i$ is not an instance of the built-in type \code{String}, throw an
\code{Error}. |
| 2942 \end{itemize} |
| 2943 Finally, the result of the evaluation of $s$ is the concatenation of the strings
$s_0$, $r_1$, \ldots{}, $r_n$, and $s_n$. |
2874 | 2944 |
2875 \subsection{Symbols} | 2945 \subsection{Symbols} |
2876 \LMLabel{symbols} | 2946 \LMLabel{symbols} |
2877 | 2947 |
2878 \LMHash{} | 2948 \LMHash{} |
2879 A {\em symbol literal} denotes the name of a declaration in a Dart program. | 2949 A {\em symbol literal} denotes the name of a declaration in a Dart program. |
2880 | 2950 |
2881 \begin{grammar} | 2951 \begin{grammar} |
2882 {\bf symbolLiteral:} | 2952 {\bf symbolLiteral:} |
2883 `\#' (operator $|$ (identifier (`{\escapegrammar .}' identifier)*)) . | 2953 `\#' (operator $|$ (identifier (`{\escapegrammar .}' identifier)*)) . |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2927 | 2997 |
2928 \LMHash{} | 2998 \LMHash{} |
2929 Let $list_1 =$ \CONST{} $<V>[e_{11} \ldots e_{1n}]$ and $list_2 =$ \CONST{} $<U
>[e_{21} \ldots e_{2n}]$ be two constant list literals and let the elements of
$list_1$ and $list_2$ evaluate to $o_{11} \ldots o_{1n}$ and $o_{21} \ldots o_
{2n}$ respectively. Iff \code{identical($o_{1i}$, $o_{2i}$)} for $i \in 1.. n$ a
nd $V = U$ then \code{identical($list_1$, $list_2$)}. | 2999 Let $list_1 =$ \CONST{} $<V>[e_{11} \ldots e_{1n}]$ and $list_2 =$ \CONST{} $<U
>[e_{21} \ldots e_{2n}]$ be two constant list literals and let the elements of
$list_1$ and $list_2$ evaluate to $o_{11} \ldots o_{1n}$ and $o_{21} \ldots o_
{2n}$ respectively. Iff \code{identical($o_{1i}$, $o_{2i}$)} for $i \in 1.. n$ a
nd $V = U$ then \code{identical($list_1$, $list_2$)}. |
2930 | 3000 |
2931 \commentary{In other words, constant list literals are canonicalized.} | 3001 \commentary{In other words, constant list literals are canonicalized.} |
2932 | 3002 |
2933 \LMHash{} | 3003 \LMHash{} |
2934 A run-time list literal $<E>[e_1 \ldots e_n]$ is evaluated as follows: | 3004 A run-time list literal $<E>[e_1 \ldots e_n]$ is evaluated as follows: |
2935 \begin{itemize} | 3005 \begin{itemize} |
2936 \item | 3006 \item |
2937 First, the expressions $e_1 \ldots e_n$ are evaluated in order they appear in th
e program, yielding objects $o_1 \ldots o_n$. | 3007 First, the expressions $e_1 \ldots e_n$ are evaluated in order they appear in th
e program, producing objects $o_1 \ldots o_n$. |
2938 \item A fresh instance (\ref{generativeConstructors}) $a$, of size $n$, whose
class implements the built-in class $List<E>$ is allocated. | 3008 \item A fresh instance (\ref{generativeConstructors}) $a$, of size $n$, whose c
lass implements the built-in class $List<E>$ is allocated. |
2939 \item | 3009 \item |
2940 The operator \code{[]=} is invoked on $a$ with first argument $i$ and second a
rgument | 3010 The operator \code{[]=} is invoked on $a$ with first argument $i$ and second a
rgument |
2941 %The $i$th element of $a$ is set to | 3011 %The $i$th element of $a$ is set to |
2942 $o_{i+1}, 0 \le i < n$. | 3012 $o_{i+1}, 0 \le i < n$. |
2943 \item | 3013 \item |
2944 The result of the evaluation is $a$. | 3014 The result of the evaluation is $a$. |
2945 \end{itemize} | 3015 \end{itemize} |
2946 | 3016 |
2947 | 3017 |
2948 \commentary{ | 3018 \commentary{ |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3003 | 3073 |
3004 \LMHash{} | 3074 \LMHash{} |
3005 Let $map_1 =$ \CONST{}$ <K, V>\{k_{11}:e_{11} \ldots k_{1n} :e_{1n}\}$ and $map
_2 =$ \CONST{}$ <J, U>\{k_{21}:e_{21} \ldots k_{2n} :e_{2n}\}$ be two constant
map literals. Let the keys of $map_1$ and $map_2$ evaluate to $s_{11} \ldots s
_{1n}$ and $s_{21} \ldots s_{2n}$ respectively, and let the elements of $map
_1$ and $map_2$ evaluate to $o_{11} \ldots o_{1n}$ and $o_{21} \ldots o_{2n}$
respectively. Iff \code{identical($o_{1i}$, $o_{2i}$)} and \code{identical($s_{
1i}$, $s_{2i}$)} for $i \in 1.. n$, and $K = J, V = U$ then \code{identical($map
_1$, $map_2$)}. | 3075 Let $map_1 =$ \CONST{}$ <K, V>\{k_{11}:e_{11} \ldots k_{1n} :e_{1n}\}$ and $map
_2 =$ \CONST{}$ <J, U>\{k_{21}:e_{21} \ldots k_{2n} :e_{2n}\}$ be two constant
map literals. Let the keys of $map_1$ and $map_2$ evaluate to $s_{11} \ldots s
_{1n}$ and $s_{21} \ldots s_{2n}$ respectively, and let the elements of $map
_1$ and $map_2$ evaluate to $o_{11} \ldots o_{1n}$ and $o_{21} \ldots o_{2n}$
respectively. Iff \code{identical($o_{1i}$, $o_{2i}$)} and \code{identical($s_{
1i}$, $s_{2i}$)} for $i \in 1.. n$, and $K = J, V = U$ then \code{identical($map
_1$, $map_2$)}. |
3006 | 3076 |
3007 \commentary{In other words, constant map literals are canonicalized.} | 3077 \commentary{In other words, constant map literals are canonicalized.} |
3008 | 3078 |
3009 \LMHash{} | 3079 \LMHash{} |
3010 A runtime map literal $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as follow
s: | 3080 A runtime map literal $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as follow
s: |
3011 \begin{itemize} | 3081 \begin{itemize} |
3012 \item | 3082 \item |
3013 First, the expression $k_i$ is evaluated yielding object $u_i$, the $e_i$ is vau
lted yielding object $o_i$, for $i \in 1..n$ in left to right order, yielding ob
jects $u_1, o_1\ldots u_n, o_n$. | 3083 For each $i \in 1..n$ in numeric order, |
3014 \item A fresh instance (\ref{generativeConstructors}) $m$ whose class implement
s the built-in class | 3084 first the expression $k_i$ is evaluated producing object $u_i$, |
3015 | 3085 and then $e_i$ is evaluated producing object $o_i$. |
3016 $Map<K, V>$ is allocated. | 3086 This produces all the objects $u_1, o_1\ldots u_n, o_n$. |
| 3087 \item A fresh instance (\ref{generativeConstructors}) $m$ whose class implement
s the built-in class $Map<K, V>$ is allocated. |
3017 \item | 3088 \item |
3018 The operator \code{[]=} is invoked on $m$ with first argument $u_i$ and second
argument $o_i, i \in 1.. n$. | 3089 The operator \code{[]=} is invoked on $m$ with first argument $u_i$ and second
argument $o_i$ for each $i \in 1.. n$. |
3019 \item | 3090 \item |
3020 The result of the evaluation is $m$. | 3091 The result of the evaluation is $m$. |
3021 \end{itemize} | 3092 \end{itemize} |
3022 | 3093 |
3023 | 3094 |
3024 \LMHash{} | 3095 \LMHash{} |
3025 A runtime map literal $\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as | 3096 A runtime map literal $\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as |
3026 | 3097 |
3027 $<\DYNAMIC{}, \DYNAMIC{}>\{k_1:e_1\ldots k_n :e_n\}$. | 3098 $<\DYNAMIC{}, \DYNAMIC{}>\{k_1:e_1\ldots k_n :e_n\}$. |
3028 | 3099 |
3029 \LMHash{} | 3100 \LMHash{} |
3030 Iff all the keys in a map literal are compile-time constants, it is a static war
ning if the values of any two keys in a map literal are equal. | 3101 Iff all the keys in a map literal are compile-time constants, it is a static war
ning if the values of any two keys in a map literal are equal. |
3031 | 3102 |
3032 \LMHash{} | 3103 \LMHash{} |
3033 A map literal is ordered: iterating over the keys and/or values of the maps alwa
ys happens in the | 3104 A map literal is ordered: iterating over the keys and/or values of the maps alwa
ys happens in the |
3034 order the keys appeared in the source code. | 3105 order the keys appeared in the source code. |
3035 | 3106 |
3036 \commentary{ | 3107 \commentary{ |
3037 Of course, if a key repeats, the order is defined by first occurrence, but the v
alue is defined by the last. | 3108 Of course, if a key repeats, the order is defined by first occurrence, but the v
alue is defined by the last. |
3038 } | 3109 } |
3039 | 3110 |
3040 \LMHash{} | 3111 \LMHash{} |
3041 The static type of a map literal of the form \CONST{}$ <K, V>\{k_1:e_1\ldots k_
n :e_n\}$ or the form $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is $Map<K, V>$. The sta
tic type a map literal of the form \CONST{}$\{k_1:e_1\ldots k_n :e_n\}$ or the
form $\{k_1:e_1\ldots k_n :e_n\}$ is $Map<\DYNAMIC{}, \DYNAMIC{}>$. | 3112 The static type of a map literal of the form \CONST{}$ <K, V>\{k_1:e_1\ldots k_
n :e_n\}$ or the form $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is $Map<K, V>$. The sta
tic type a map literal of the form \CONST{}$\{k_1:e_1\ldots k_n :e_n\}$ or the
form $\{k_1:e_1\ldots k_n :e_n\}$ is $Map<\DYNAMIC{}, \DYNAMIC{}>$. |
3042 | 3113 |
3043 | 3114 |
3044 \subsection{Throw} | 3115 \subsection{Throw} |
3045 \LMLabel{throw} | 3116 \LMLabel{throw} |
3046 | 3117 |
3047 \LMHash{} | 3118 \LMHash{} |
3048 The {\em throw expression} is used to raise an exception. | 3119 The {\em throw expression} is used to throw an exception. |
3049 | 3120 |
3050 \begin{grammar} | 3121 \begin{grammar} |
3051 {\bf throwExpression:} | 3122 {\bf throwExpression:} |
3052 \THROW{} expression | 3123 \THROW{} expression |
3053 . | 3124 . |
3054 | 3125 |
3055 {\bf throwExpressionWithoutCascade:} | 3126 {\bf throwExpressionWithoutCascade:} |
3056 \THROW{} expressionWithoutCascade | 3127 \THROW{} expressionWithoutCascade |
3057 . | 3128 . |
3058 | 3129 |
3059 \end{grammar} | 3130 \end{grammar} |
3060 | 3131 |
3061 \LMHash{} | 3132 \LMHash{} |
3062 The {\em current exception} is the last exception raised and not subsequently c
aught at a given moment during runtime. | 3133 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as f
ollows: |
3063 | 3134 |
3064 \LMHash{} | 3135 \LMHash{} |
3065 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as
follows: | 3136 The expression $e$ is evaluated to a value $v$ (\ref{evaluation}). |
3066 | |
3067 \LMHash{} | |
3068 The expression $e$ is evaluated yielding a value $v$. | |
3069 | 3137 |
3070 \commentary{ | 3138 \commentary{ |
3071 There is no requirement that the expression $e$ evaluate to a special kind of ex
ception or error object. | 3139 There is no requirement that the expression $e$ evaluate to any special kind of
object. |
3072 } | 3140 } |
3073 | 3141 |
3074 \LMHash{} | 3142 \LMHash{} |
3075 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. | 3143 If $v$ is the null value (\ref{null}), then a \code{NullThrownError} is thrown. |
3076 | 3144 Otherwise let $t$ be a stack trace corresponding to the current execution state, |
3077 \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. | 3145 and the \THROW{} statement throws with $v$ as exception object |
3078 } | 3146 and $t$ as stack trace (\ref{evaluation}). |
3079 | 3147 |
3080 \LMHash{} | 3148 \LMHash{} |
3081 Let $f$ be the immediately enclosing function. | 3149 If $v$ is an instance of class \code{Error} or a subclass thereof, |
3082 | 3150 and it is the first time that \code{Error} object is thrown, |
3083 \LMHash{} | 3151 the stack trace $t$ is stored on $v$ so that it will be returned |
3084 If $f$ is synchronous (\ref{functions}), control is transferred to the nearest d
ynamically enclosing exception handler. | 3152 by the $v$'s \code{stackTrace} getter |
3085 | 3153 |
3086 \commentary{ | 3154 \commentary{ |
3087 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. | 3155 If the same \code{Error} object is thrown more than once, its \code{stackTrace}
getter will return the stack trace from the {\em first} time it was thrown. |
3088 } | 3156 } |
3089 | 3157 |
3090 \LMHash{} | 3158 \LMHash{} |
3091 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. | |
3092 | |
3093 \rationale{ | |
3094 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. | |
3095 } | |
3096 | |
3097 \LMHash{} | |
3098 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. | |
3099 | |
3100 \LMHash{} | |
3101 The static type of a throw expression is $\bot$. | 3159 The static type of a throw expression is $\bot$. |
3102 | 3160 |
3103 | 3161 |
3104 \subsection{ Function Expressions} | 3162 \subsection{ Function Expressions} |
3105 \LMLabel{functionExpressions} | 3163 \LMLabel{functionExpressions} |
3106 | 3164 |
3107 \LMHash{} | 3165 \LMHash{} |
3108 A {\em function literal} is an object that encapsulates an executable unit of co
de. | 3166 A {\em function literal} is an object that encapsulates an executable unit of co
de. |
3109 | 3167 |
3110 \begin{grammar} | 3168 \begin{grammar} |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3352 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}
: a_{n+k})$ is evaluated. | 3410 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}
: a_{n+k})$ is evaluated. |
3353 | 3411 |
3354 \LMHash{} | 3412 \LMHash{} |
3355 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully
loaded, a dynamic error occurs. | 3413 If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully
loaded, a dynamic error occurs. |
3356 | 3414 |
3357 \LMHash{} | 3415 \LMHash{} |
3358 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs
tractClassInstantiationError} is thrown. | 3416 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs
tractClassInstantiationError} is thrown. |
3359 | 3417 |
3360 \LMHash{} | 3418 \LMHash{} |
3361 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. | 3419 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. |
3362 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. | 3420 Otherwise, if $q$ is not defined or not accessible, a \code{NoSuchMethodError} i
s thrown. If $q$ has fewer 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. |
3363 | 3421 |
3364 \LMHash{} | 3422 \LMHash{} |
3365 Otherwise, if $q$ is a generative constructor (\ref{generativeConstructors}), th
en: | 3423 Otherwise, if $q$ is a generative constructor (\ref{generativeConstructors}), th
en: |
3366 | 3424 |
3367 \commentary{Note that it this point we are assured that the number of actual typ
e arguments match the number of formal type parameters.} | 3425 \commentary{Note that at this point we are assured that the number of actual typ
e arguments match the number of formal type parameters.} |
3368 | 3426 |
3369 \LMHash{} | 3427 \LMHash{} |
3370 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{}. | 3428 A fresh instance (\ref{generativeConstructors}), $i$, of class $R$ is allocated. |
| 3429 Then $q$ is executed to initialize $i$ with respect to the bindings that resulte
d from the evaluation of the argument list, and, if $R$ is a generic class, with
its type parameters bound to $V_1 \ldots V_m$. |
3371 | 3430 |
3372 \commentary{ | 3431 If execution of $q$ completes normally (\ref{completion}), $e$ evaluates to $i$. |
3373 Observe that \THIS{} is not in scope in $e_f$. Hence, the initialization cannot
depend on other properties of the object being instantiated. | 3432 Otherwise execution of $q$ throws an exception object $x$ and stack trace $t$, |
3374 } | 3433 and then evaluation of $e$ also throws exception object $x$ and stack trace $t$ |
3375 | 3434 (\ref{evaluation}). |
3376 \LMHash{} | |
3377 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$. | |
3378 | 3435 |
3379 \LMHash{} | 3436 \LMHash{} |
3380 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: | 3437 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: |
3381 | 3438 |
3382 \LMHash{} | 3439 \LMHash{} |
3383 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 | 3440 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 |
3384 | 3441 |
3385 $[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. | 3442 $[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. |
| 3443 % 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. |
3386 | 3444 |
3387 | 3445 |
3388 \LMHash{} | 3446 \LMHash{} |
3389 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$. | 3447 Otherwise, the body of $q$ is executed with respect to the bindings that resulte
d from the evaluation of the argument list, and with the type parameters (if any
) of $q$ bound to the actual type arguments $V_1, \ldots, V_l$. |
| 3448 If this execution returns a value (\ref{completion}), |
| 3449 then $e$ evaluates to the returned value. |
| 3450 Otherwise, if the execution completes normally or returns with no value, |
| 3451 then $e$ evaluates to \NULL. |
| 3452 Otherwise the execution throws an exception $x$ and stack trace $t$, |
| 3453 and then evaluation of $e$ also throws $x$ and $t$ (\ref{evaluation}). |
3390 | 3454 |
3391 \LMHash{} | 3455 \LMHash{} |
3392 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n
ot a factory constructor. | 3456 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n
ot a factory constructor. |
3393 | 3457 |
3394 \commentary{The above gives precise meaning to the idea that instantiating an ab
stract class leads to a warning. | 3458 \commentary{The above gives precise meaning to the idea that instantiating an ab
stract class leads to a warning. |
3395 A similar clause applies to constant object creation in the next section. | 3459 A similar clause applies to constant object creation in the next section. |
3396 } | 3460 } |
3397 | 3461 |
3398 \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. | 3462 \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. |
3399 } | 3463 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3543 | 3607 |
3544 | 3608 |
3545 | 3609 |
3546 \subsection{ Function Invocation} | 3610 \subsection{ Function Invocation} |
3547 \LMLabel{functionInvocation} | 3611 \LMLabel{functionInvocation} |
3548 | 3612 |
3549 \LMHash{} | 3613 \LMHash{} |
3550 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. | 3614 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. |
3551 | 3615 |
3552 \LMHash{} | 3616 \LMHash{} |
3553 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. | 3617 If $f$ is synchronous and is not a generator (\ref{functions}) then execution of
the body of $f$ begins immediately. |
| 3618 If the execution of the body of $f$ returns a value, $v$, (\ref{completion}), th
e invocation evaluates to $v$. |
| 3619 If the execution completes normally or it returns without a value, the invocatio
n evaluates to \NULL (\ref{null}). |
| 3620 If the execution throws an exception object and stack trace, the invocation thro
ws the same exception object and stack trace (\ref{evaluation}). |
3554 | 3621 |
3555 \LMHash{} | 3622 \commentary{ |
3556 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: | 3623 A complete function body can never break or contine (\ref{completion}) |
3557 \begin{itemize} | 3624 because a \BREAK{} or \CONTINUE{} statement must always occur inside the stateme
nt that is the target of the \BREAK{} or \CONTINUE{}. |
3558 \item If the current return value is defined then, if $s$ has been canceled then
its cancellation future is completed with \NULL{} (\ref{null}). | 3625 This means that a function body can only either complete normally, throw, or ret
urn. Completing normally or returning without a value is treated the same as ret
urning \NULL, so the result of executing a function body can always be used as t
he result of evaluating an expression, either by evaluating to a value or by the
evaluation throwing. |
3559 \item If the current exception $x$ is defined: | |
3560 \begin{itemize} | |
3561 \item $x$ is added to $s$. | |
3562 \item If $s$ has been canceled then its cancellation future is completed with
$x$ as an error. | |
3563 \end{itemize} | |
3564 \item $s$ is closed. | |
3565 \end{itemize} | |
3566 | |
3567 \rationale{ | |
3568 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. | |
3569 } | 3626 } |
3570 | 3627 |
3571 \LMHash{} | |
3572 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. | |
3573 | |
3574 \rationale{Such streams may be left open by for loops that were escaped when an
exception was thrown within them for example. | |
3575 } | |
3576 | |
3577 %\LMHash{} | |
3578 %When a stream is canceled, the implementation must wait for the cancelation fut
ure returned by \cd{cancell()} to complete before proceeding. | |
3579 | 3628 |
3580 \LMHash{} | 3629 \LMHash{} |
3581 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. | 3630 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. |
3582 | 3631 |
3583 | |
3584 \commentary{ | 3632 \commentary{ |
3585 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}. | 3633 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}. |
3586 } | 3634 } |
3587 | 3635 |
3588 \LMHash{} | 3636 \LMHash{} |
3589 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. | 3637 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. |
3590 | 3638 |
3591 \commentary { | 3639 \commentary { |
3592 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. | 3640 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. |
3593 } | 3641 } |
3594 | 3642 |
3595 \LMHash{} | 3643 \LMHash{} |
3596 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. | 3644 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 execution of the body of $f$ completes (\ref{completion}, |
| 3645 \begin{itemize} |
| 3646 \item If it returns without a value or it completes normally (\ref{completion}),
$j$ is positioned after its last element, so that its current value is \code{nu
ll} and the current call to \code{moveNext()} on $j$ returns false, as must all
further calls. |
| 3647 \item If it throws an exception object $e$ and stack trace $t$ then the current
value of $j$ is \NULL and the current call to \code{moveNext()} throws $e$ and $
t$ as well. Further calls to \code{moveNext()} must return false. |
| 3648 \end{itemize} |
3597 | 3649 |
3598 Each iterator starts a separate computation. If the \SYNC* function is impure, t
he sequence of values yielded by each iterator may differ. | 3650 Each iterator starts a separate computation. If the \SYNC* function is impure, t
he sequence of values yielded by each iterator may differ. |
3599 | 3651 |
3600 \commentary{ | 3652 \commentary{ |
3601 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 | 3653 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 |
3602 writing an \code{Iterator} class. In particular, it should handle multiple | 3654 writing an \code{Iterator} class. In particular, it should handle multiple |
3603 simultaneous iterators gracefully. If the iterator depends on external state | 3655 simultaneous iterators gracefully. If the iterator depends on external state |
3604 that might change, it should check that the state is still valid after every | 3656 that might change, it should check that the state is still valid after every |
3605 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). | 3657 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). |
3606 } | 3658 } |
3607 | 3659 |
3608 \LMHash{} | 3660 \LMHash{} |
3609 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. | 3661 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. |
3610 \commentary{ | 3662 \commentary{ |
3611 Two executions of an iterator interact only via state outside the function. | 3663 Two executions of an iterator interact only via state outside the function. |
3612 } | 3664 } |
3613 % 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. | 3665 % 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. |
3614 | 3666 |
| 3667 \LMHash{} |
| 3668 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 be completed w
hen execution of the body of $f$ completes (\ref{completion}). If execution of t
he body returns a value, $o$ is completed with that value, if it completes norma
lly or returns without a value, $o$ is completed with the \NULL{} value, and if
it throws an exception $e$ and stack trace $t$, $o$ is completed with the error
$e$ and stack trace $t$. |
3615 | 3669 |
3616 \LMHash{} | 3670 \LMHash{} |
3617 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. | 3671 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
. |
| 3672 When execution of the body of $f$ completes: |
| 3673 \begin{itemize} |
| 3674 \item If it completes normally or returns with no value (\ref{completion}), then
if $s$ has been canceled then its cancellation future is completed with \NULL{}
(\ref{null}). |
| 3675 \item If it throws an exception object $e$ and stack trace $t$: |
| 3676 \begin{itemize} |
| 3677 \item If $s$ has been canceled then its cancellation future is completed with
error $e$ and stack trace $t$. |
| 3678 \item otherwise the error $e$ and stack trace $t$ are emitted by $s$. |
| 3679 \end{itemize} |
| 3680 \item $s$ is closed. |
| 3681 \end{itemize} |
| 3682 \commentary{ |
| 3683 The body of an asynchronous generator function cannot break, continue or return
a value (\ref{completion}). The first two are only allowed in contexts that will
handle the break or continue, and return statements with an expression are not
allowed in generator functions. |
| 3684 } |
3618 | 3685 |
| 3686 \rationale{ |
| 3687 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. |
| 3688 } |
3619 | 3689 |
3620 \LMHash{} | 3690 %\LMHash{} |
3621 Execution of $f$ terminates when the first of the following occurs: | 3691 %When a stream is canceled, the implementation must wait for the cancelation fut
ure returned by \cd{cancell()} to complete before proceeding. |
3622 \begin{itemize} | |
3623 \item An exception is thrown and not caught within the current function activati
on. | |
3624 \item A return statement (\ref{return}) immediately nested in the body of $f$ is
executed and not intercepted in a \FINALLY{} (\ref{try}) clause. | |
3625 \item The last statement of the body completes execution. | |
3626 \end{itemize} | |
3627 | |
3628 | |
3629 | |
3630 | 3692 |
3631 \subsubsection{ Actual Argument List Evaluation} | 3693 \subsubsection{ Actual Argument List Evaluation} |
3632 \LMLabel{actualArguments} | 3694 \LMLabel{actualArguments} |
3633 | 3695 |
3634 \LMHash{} | 3696 \LMHash{} |
3635 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. | 3697 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. |
3636 | 3698 |
3637 \begin{grammar} | 3699 \begin{grammar} |
3638 {\bf arguments:} | 3700 {\bf arguments:} |
3639 `(' (argumentList `,'?)? `)' | 3701 `(' (argumentList `,'?)? `)' |
(...skipping 14 matching lines...) Expand all Loading... |
3654 Argument lists allow an optional trailing comma after the last argument ($`,'?$)
. An argument list with such a trailing comma is equivalent in all ways to the s
ame parameter list without the trailing comma. All argument lists in this specif
ication are shown without a trailing comma, but the rules and semantics apply eq
ually to the corresponding argument list with a trailing comma. | 3716 Argument lists allow an optional trailing comma after the last argument ($`,'?$)
. An argument list with such a trailing comma is equivalent in all ways to the s
ame parameter list without the trailing comma. All argument lists in this specif
ication are shown without a trailing comma, but the rules and semantics apply eq
ually to the corresponding argument list with a trailing comma. |
3655 | 3717 |
3656 \LMHash{} | 3718 \LMHash{} |
3657 Evaluation of an actual argument list of the form | 3719 Evaluation of an actual argument list of the form |
3658 | 3720 |
3659 $(a_1, \ldots, a_m, q_1: a_{m+1}, \ldots, q_l: a_{m+l})$ | 3721 $(a_1, \ldots, a_m, q_1: a_{m+1}, \ldots, q_l: a_{m+l})$ |
3660 | 3722 |
3661 proceeds as follows: | 3723 proceeds as follows: |
3662 | 3724 |
3663 \LMHash{} | 3725 \LMHash{} |
3664 The arguments $a_1, \ldots, a_{m+l}$ are evaluated in the order they appear in t
he program, yielding objects $o_1, \ldots, o_{m+l}$. | 3726 The arguments $a_1, \ldots, a_{m+l}$ are evaluated in the order they appear in t
he program, producing objects $o_1, \ldots, o_{m+l}$. |
3665 | 3727 |
3666 \commentary{Simply stated, an argument list consisting of $m$ positional argumen
ts and $l$ named arguments is evaluated from left to right. | 3728 \commentary{Simply stated, an argument list consisting of $m$ positional argumen
ts and $l$ named arguments is evaluated from left to right. |
3667 } | 3729 } |
3668 | 3730 |
3669 | 3731 |
3670 \subsubsection{ Binding Actuals to Formals} | 3732 \subsubsection{ Binding Actuals to Formals} |
3671 \LMLabel{bindingActualsToFormals} | 3733 \LMLabel{bindingActualsToFormals} |
3672 | 3734 |
3673 \LMHash{} | 3735 \LMHash{} |
3674 Let $f$ be a function with $h$ required parameters, let $p_1 \ldots p_n$ be the
positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+k}$ be the optional
parameters declared by $f$. | 3736 Let $f$ be a function with $h$ required parameters, let $p_1 \ldots p_n$ be the
positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+k}$ be the optional
parameters declared by $f$. |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3978 | 4040 |
3979 \LMHash{} | 4041 \LMHash{} |
3980 A super method invocation $i$ has the form | 4042 A super method invocation $i$ has the form |
3981 | 4043 |
3982 $\SUPER{}.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. | 4044 $\SUPER{}.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
3983 | 4045 |
3984 \LMHash{} | 4046 \LMHash{} |
3985 Evaluation of $i$ proceeds as follows: | 4047 Evaluation of $i$ proceeds as follows: |
3986 | 4048 |
3987 \LMHash{} | 4049 \LMHash{} |
3988 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}
: a_{n+k})$ is evaluated yielding actual argument objects $o_1, \ldots , o_{n+k
}$. Let $g$ be the method currently executing, and let $C$ be the class in which
$g$ was looked up (\ref{methodLookup}). Let $S_{dynamic}$ be the superclass of
$C$, and let $f$ be the result of looking up method (\ref{methodLookup}) $m$ in
$S_{dynamic}$ with respect to the current library $L$. | 4050 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}
: a_{n+k})$ is evaluated producing actual argument objects $o_1, \ldots , o_{n+k
}$. Let $g$ be the method currently executing, and let $C$ be the class in which
$g$ was looked up (\ref{methodLookup}). Let $S_{dynamic}$ be the superclass of
$C$, and let $f$ be the result of looking up method (\ref{methodLookup}) $m$ in
$S_{dynamic}$ with respect to the current library $L$. |
3989 Let $p_1 \ldots p_h$ be the required parameters of $f$, let $p_1 \ldots p_m$ be
the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+l}$ be the opti
onal parameters declared by $f$. | 4051 Let $p_1 \ldots p_h$ be the required parameters of $f$, let $p_1 \ldots p_m$ be
the positional parameters of $f$ and let $p_{h+1}, \ldots, p_{h+l}$ be the opti
onal parameters declared by $f$. |
3990 | 4052 |
3991 \LMHash{} | 4053 \LMHash{} |
3992 If $n < h$, or $n > m$, the method lookup has failed. Furthermore, each $x_i, n
+1 \le i \le n+k$, must have a corresponding named parameter in the set $\{p_{m
+1}, \ldots, p_{h+l}\}$ or the method lookup also fails. Otherwise method looku
p has succeeded. | 4054 If $n < h$, or $n > m$, the method lookup has failed. Furthermore, each $x_i, n
+1 \le i \le n+k$, must have a corresponding named parameter in the set $\{p_{m
+1}, \ldots, p_{h+l}\}$ or the method lookup also fails. Otherwise method looku
p has succeeded. |
3993 | 4055 |
3994 \LMHash{} | 4056 \LMHash{} |
3995 If the method lookup succeeded, the body of $f$ is executed with respect to the
bindings that resulted from the evaluation of the argument list, and with \THIS{
} bound to the current value of \THIS{}. The value of $i$ is the value returned
after $f$ is executed. | 4057 If the method lookup succeeded, the body of $f$ is executed with respect to the
bindings that resulted from the evaluation of the argument list, and with \THIS{
} bound to the current value of \THIS{}. The value of $i$ is the value returned
after $f$ is executed. |
3996 | 4058 |
3997 \LMHash{} | 4059 \LMHash{} |
3998 If the method lookup has failed, then let $g$ be the result of looking up getter
(\ref{getterAndSetterLookup}) $m$ in $S_{dynamic}$ with respect to $L$. If the
getter lookup succeeded, let $v_g$ be the value of the getter invocation $\SUPER
{}.m$. Then the value of $i$ is the result of invoking | 4060 If the method lookup has failed, then let $g$ be the result of looking up getter
(\ref{getterAndSetterLookup}) $m$ in $S_{dynamic}$ with respect to $L$. If the
getter lookup succeeded, let $v_g$ be the value of the getter invocation $\SUPER
{}.m$. Then the value of $i$ is the result of invoking |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4424 | 4486 |
4425 | 4487 |
4426 | 4488 |
4427 \subsubsection{Compound Assignment} | 4489 \subsubsection{Compound Assignment} |
4428 \LMLabel{compoundAssignment} | 4490 \LMLabel{compoundAssignment} |
4429 | 4491 |
4430 \LMHash{} | 4492 \LMHash{} |
4431 Evaluation of a compound assignment $a$ of the form \code{$v$ ??= $e$} | 4493 Evaluation of a compound assignment $a$ of the form \code{$v$ ??= $e$} |
4432 proceeds as follows: | 4494 proceeds as follows: |
4433 | 4495 |
| 4496 \LMHash{} |
4434 Evaluate $v$ to an object $o$. | 4497 Evaluate $v$ to an object $o$. |
4435 If $o$ is not the null value, $a$ evaluates to $o$. | 4498 If $o$ is not the null value, $a$ evaluates to $o$. |
4436 Otherwise evaluate \code{$v$ = $e$} to a value $r$, | 4499 Otherwise evaluate \code{$v$ = $e$} to a value $r$, |
4437 and then $a$ evaluates to $r$. | 4500 and then $a$ evaluates to $r$. |
4438 | 4501 |
4439 \LMHash{} | 4502 \LMHash{} |
4440 Evaluation of a compound assignment, $a$ of the form \code{$C$.$v$ ??= $e$}, whe
re $C$ is a type literal, proceeds as follow: | 4503 Evaluation of a compound assignment, $a$ of the form \code{$C$.$v$ ??= $e$}, whe
re $C$ is a type literal, proceeds as follow: |
4441 | 4504 |
| 4505 \LMHash{} |
4442 Evaluate \code{$C$.$v$} to an object $o$. | 4506 Evaluate \code{$C$.$v$} to an object $o$. |
4443 If $o$ is not the null value, $a$ evaluates to $o$. | 4507 If $o$ is not the null value, $a$ evaluates to $o$. |
4444 Otherwise evaluate \code{$C$.$v$ = $e$} to a value $r$, | 4508 Otherwise evaluate \code{$C$.$v$ = $e$} to a value $r$, |
4445 and then $a$ evaluates to $r$. | 4509 and then $a$ evaluates to $r$. |
4446 | 4510 |
4447 \commentary { | 4511 \commentary { |
4448 The two rules above also apply when the variable v or the type C is prefixed. | 4512 The two rules above also apply when the variable v or the type C is prefixed. |
4449 } | 4513 } |
4450 | 4514 |
4451 \LMHash{} | 4515 \LMHash{} |
4452 Evaluation of a compound assignment $a$ of the form \code{$e_1$.$v$ ??= $e_2$} | 4516 Evaluation of a compound assignment $a$ of the form \code{$e_1$.$v$ ??= $e_2$} |
4453 proceeds as follows: | 4517 proceeds as follows: |
4454 | 4518 |
4455 \LMHash{} | 4519 \LMHash{} |
4456 Evaluate $e_1$ to an object $u$. | 4520 Evaluate $e_1$ to an object $u$. |
4457 Let $x$ be a fresh variable bound to $u$. | 4521 Let $x$ be a fresh variable bound to $u$. |
4458 Evalute \code{$x$.$v$} to an object $o$. | 4522 Evaluate \code{$x$.$v$} to an object $o$. |
4459 If $o$ is not the null value, $a$ evaluates to $o$. | 4523 If $o$ is not the null value, $a$ evaluates to $o$. |
4460 Otherwise evaluate \code{$x$.$v$ = $e_2$} to an object $r$, | 4524 Otherwise evaluate \code{$x$.$v$ = $e_2$} to an object $r$, |
4461 and then $a$ evaluates to $r$. | 4525 and then $a$ evaluates to $r$. |
4462 | 4526 |
4463 \LMHash{} | 4527 \LMHash{} |
4464 Evaluation of a compound assignment $a$ of the form \code{$e_1$[$e_2$] ??= $e_3$
} | 4528 Evaluation of a compound assignment $a$ of the form \code{$e_1$[$e_2$] ??= $e_3$
} |
4465 proceeds as follows: | 4529 proceeds as follows: |
4466 | 4530 |
4467 \LMHash{} | 4531 \LMHash{} |
4468 Evaluate $e_1$ to an object $u$ and then evaluate $e_2$ to an object $i$. | 4532 Evaluate $e_1$ to an object $u$ and then evaluate $e_2$ to an object $i$. |
4469 Call the \code{[]} method on $u$ with argument $i$, and let $o$ be the returned
value. | 4533 Call the \code{[]} method on $u$ with argument $i$, and let $o$ be the returned
value. |
4470 If $o$ is not the null value, $a$ evaluates to $o$. | 4534 If $o$ is not the null value, $a$ evaluates to $o$. |
4471 Otherwise evaluate $e_3$ to an object $v$ | 4535 Otherwise evaluate $e_3$ to an object $v$ |
4472 and then call the \code{[]=} method on $u$ with $i$ as first argument and $v$ as
second argument. | 4536 and then call the \code{[]=} method on $u$ with $i$ as first argument and $v$ as
second argument. |
4473 Then $a$ evaluates to $v$. | 4537 Then $a$ evaluates to $v$. |
4474 | 4538 |
4475 \LMHash{} | 4539 \LMHash{} |
4476 Evaluation of a compound assignment $a$ of the form \code{\SUPER.$v$ ??= $e$} | 4540 Evaluation of a compound assignment $a$ of the form \code{\SUPER.$v$ ??= $e$} |
4477 proceeds as follows: | 4541 proceeds as follows: |
4478 | 4542 |
4479 \LMHash{} | 4543 \LMHash{} |
4480 Evaluate \code{\SUPER.$v$} to an object $o$. | 4544 Evaluate \code{\SUPER.$v$} to an object $o$. |
4481 If $o$ is not the null value then $a$ evaluats to $o$. | 4545 If $o$ is not the null value then $a$ evaluates to $o$. |
4482 Otherwise evaluate \code{\SUPER.$v$ = $e$} to an object $r$, | 4546 Otherwise evaluate \code{\SUPER.$v$ = $e$} to an object $r$, |
4483 and then $a$ evaluates to $r$. | 4547 and then $a$ evaluates to $r$. |
4484 | 4548 |
4485 \LMHash{} | 4549 \LMHash{} |
4486 Evaluation of a compound assignment $a$ of the form \code{$e_1$?.$v$ ??= $e_2$} | 4550 Evaluation of a compound assignment $a$ of the form \code{$e_1$?.$v$ ??= $e_2$} |
4487 proceeds as follows: | 4551 proceeds as follows: |
4488 | 4552 |
4489 \LMHash{} | 4553 \LMHash{} |
4490 Evaluate $e_1$ to an object $u$ and let $x$ be a fresh variable bound to $u$. | 4554 Evaluate $e_1$ to an object $u$ and let $x$ be a fresh variable bound to $u$. |
4491 Evaluate \code{$x$.$v$} to an object $o$. | 4555 Evaluate \code{$x$.$v$} to an object $o$. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4636 {\bf logicalAndExpression:} | 4700 {\bf logicalAndExpression:} |
4637 equalityExpression (`\&\&' equalityExpression)* | 4701 equalityExpression (`\&\&' equalityExpression)* |
4638 % bitwiseOrExpression (`\&\&' bitwiseOrExpression)* | 4702 % bitwiseOrExpression (`\&\&' bitwiseOrExpression)* |
4639 . | 4703 . |
4640 \end{grammar} | 4704 \end{grammar} |
4641 | 4705 |
4642 \LMHash{} | 4706 \LMHash{} |
4643 A {\em logical boolean expression} is either an equality expression (\ref{equali
ty}), or an invocation of a logical boolean operator on an expression $e_1$ with
argument $e_2$. | 4707 A {\em logical boolean expression} is either an equality expression (\ref{equali
ty}), or an invocation of a logical boolean operator on an expression $e_1$ with
argument $e_2$. |
4644 | 4708 |
4645 \LMHash{} | 4709 \LMHash{} |
4646 Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes t
he evaluation of $e_1$ which is then subjected to boolean conversion, yielding
an object $o_1$; if $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, other
wise $e_2$ is evaluated to an object $o_2$, which is then subjected to boolean c
onversion (\ref{booleanConversion}) producing an object $r$, which is the value
of $b$. | 4710 Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes t
he evaluation of $e_1$ which is then subjected to boolean conversion, producing
an object $o_1$; if $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, othe
rwise $e_2$ is evaluated to an object $o_2$, which is then subjected to boolean
conversion (\ref{booleanConversion}) producing an object $r$, which is the value
of $b$. |
4647 | 4711 |
4648 \LMHash{} | 4712 \LMHash{} |
4649 Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes
the evaluation of $e_1$ which is then subjected to boolean conversion, yielding
an object $o_1$; if $o_1$ is not \TRUE, the result of evaluating $b$ is \FALSE
, otherwise $e_2$ is evaluated to an object $o_2$, which is then subjected to bo
olean conversion producing an object $r$, which is the value of $b$. | 4713 Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes
the evaluation of $e_1$ which is then subjected to boolean conversion, producin
g an object $o_1$; if $o_1$ is not \TRUE, the result of evaluating $b$ is \FALS
E, otherwise $e_2$ is evaluated to an object $o_2$, which is then subjected to b
oolean conversion evaluating to an object $r$, which is the value of $b$. |
4650 | 4714 |
4651 \LMHash{} | 4715 \LMHash{} |
4652 A logical boolean expression $b$ of the form $e_1 \&\& e_2$ shows that a variabl
e $v$ has type | 4716 A logical boolean expression $b$ of the form $e_1 \&\& e_2$ shows that a variabl
e $v$ has type |
4653 $T$ if all of the following conditions hold: | 4717 $T$ if all of the following conditions hold: |
4654 \begin{itemize} | 4718 \begin{itemize} |
4655 \item Either $e_1$ shows that $v$ has type $T$ or $e_2$ shows that $v$ has type
$T$. | 4719 \item Either $e_1$ shows that $v$ has type $T$ or $e_2$ shows that $v$ has type
$T$. |
4656 \item $v$ is a local variable or formal parameter. | 4720 \item $v$ is a local variable or formal parameter. |
4657 \item The variable $v$ is not mutated in $e_2$ or within a closure. | 4721 \item The variable $v$ is not mutated in $e_2$ or within a closure. |
4658 \end{itemize} | 4722 \end{itemize} |
4659 | 4723 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4926 \LMHash{} | 4990 \LMHash{} |
4927 An {\em await expression} allows code to yield control until an asynchronous ope
ration (\ref{functions}) completes. | 4991 An {\em await expression} allows code to yield control until an asynchronous ope
ration (\ref{functions}) completes. |
4928 | 4992 |
4929 \begin{grammar} | 4993 \begin{grammar} |
4930 {\bf awaitExpression:} | 4994 {\bf awaitExpression:} |
4931 \AWAIT{} unaryExpression | 4995 \AWAIT{} unaryExpression |
4932 \end{grammar} | 4996 \end{grammar} |
4933 | 4997 |
4934 \LMHash{} | 4998 \LMHash{} |
4935 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follo
ws: | 4999 Evaluation of an await expression $a$ of the form \AWAIT{} $e$ proceeds as follo
ws: |
4936 First, the expression $e$ is evaluated. Next: | 5000 First, the expression $e$ is evaluated to an object $o$. |
4937 | 5001 |
4938 \LMHash{} | 5002 \LMHash{} |
4939 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$. | 5003 % NOTICE: Removed the requirement that an error thrown by $e$ is caught in a |
| 5004 % future. There is no reason $var x = e; await x;$ and $await e$ should behave |
| 5005 % differently, and no implementation actually implemented it. |
| 5006 Then, if $o$ is not an instance of \code{Future}, then let $f$ be the result of
creating a new object using the constructor \code{Future.value()} with $o$ as it
s argument; otherwise let $f$ be $o$. |
4940 | 5007 |
4941 \LMHash{} | 5008 \LMHash{} |
4942 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$. | 5009 Next, the stream associated with the innermost enclosing asynchronous for loop (
\ref{asynchronousFor-in}), if any, is paused. The current invocation of the func
tion body immediately enclosing $a$ is suspended until after $f$ completes. At s
ome time after $f$ is completed, control returns to the current invocation. If $
f$ has completed with an error $x$ and stack trace $t$, $a$ throws $x$ and $t$ (
\ref{evaluation}). If $f$ completes with a value $v$, $a$ evaluates to $v$. |
4943 | 5010 |
4944 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an
exception $x$, $a$ raises $x$. | 5011 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an
exception $x$, $a$ raises $x$. |
4945 | 5012 |
4946 \commentary{ | 5013 \commentary{ |
4947 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. | 5014 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. |
| 5015 % TODO(lrn): Update this, it's not actually correct, |
| 5016 % the expression "await(expr)" is valid non-async syntax *and* a valid |
| 5017 % async await expression. |
4948 } | 5018 } |
4949 | 5019 |
4950 \rationale{ | 5020 \rationale{ |
4951 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. | 5021 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. |
4952 } | 5022 } |
4953 | 5023 |
4954 \commentary{ | 5024 \commentary{ |
4955 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. | 5025 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. |
4956 } | 5026 } |
4957 | 5027 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5123 \LMHash{} | 5193 \LMHash{} |
5124 The static type of such an expression is the static type of \code{$e_1$.$v$}. | 5194 The static type of such an expression is the static type of \code{$e_1$.$v$}. |
5125 | 5195 |
5126 \LMHash{} | 5196 \LMHash{} |
5127 Evaluation of a postfix expression $e$ of the form \code{$e_1$?.$v$-{}-} | 5197 Evaluation of a postfix expression $e$ of the form \code{$e_1$?.$v$-{}-} |
5128 where $e_1$ is not a type literal, proceeds as follows: | 5198 where $e_1$ is not a type literal, proceeds as follows: |
5129 | 5199 |
5130 If $e_1$ is a type literal, $e$ is equivalent to \code{$e_1$.$v$-{}-}. | 5200 If $e_1$ is a type literal, $e$ is equivalent to \code{$e_1$.$v$-{}-}. |
5131 | 5201 |
5132 Otherwise evaluate $e_1$ to an object $u$. | 5202 Otherwise evaluate $e_1$ to an object $u$. |
5133 If $u$ is the null value, $e$ evalkuates to the null value. | 5203 If $u$ is the null value, $e$ evaluates to the null value. |
5134 Otherwise let $x$ be a fresh variable bound to $u$. | 5204 Otherwise let $x$ be a fresh variable bound to $u$. |
5135 Evaluate \code{$x$.$v$-{}-} to an object $o$. | 5205 Evaluate \code{$x$.$v$-{}-} to an object $o$. |
5136 Then $e$ evaluates to $o$. | 5206 Then $e$ evaluates to $o$. |
5137 | 5207 |
5138 | 5208 |
5139 \LMHash{} | 5209 \LMHash{} |
5140 The static type of such an expression is the static type of \code{$e_1$.$v$}. | 5210 The static type of such an expression is the static type of \code{$e_1$.$v$}. |
5141 | 5211 |
5142 | 5212 |
5143 \subsection{ Assignable Expressions} | 5213 \subsection{ Assignable Expressions} |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5401 \LMHash{} | 5471 \LMHash{} |
5402 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$. | 5472 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$. |
5403 In all other cases, a \code{CastError} is thrown. | 5473 In all other cases, a \code{CastError} is thrown. |
5404 | 5474 |
5405 \LMHash{} | 5475 \LMHash{} |
5406 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. | 5476 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. |
5407 | 5477 |
5408 \section{Statements} | 5478 \section{Statements} |
5409 \LMLabel{statements} | 5479 \LMLabel{statements} |
5410 | 5480 |
| 5481 \LMHash{} |
| 5482 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 and control flow. |
| 5483 |
| 5484 \label{completion} |
| 5485 Execution of a statement {\em completes} in one of five ways: either it {\em com
pletes normally}, it {\em breaks} or it {\em continues} (either to a label or wi
thout a label), it {\em returns} (with or without a value), or it {\em throws} a
n exception object and an associated stack trace. |
| 5486 |
| 5487 In the description of statement execution, the default is that the execution |
| 5488 completes normally unless otherwise stated. |
| 5489 |
| 5490 If the execution of a statement, $s$, is defined in terms of executing |
| 5491 another statement, |
| 5492 and the execution of that other statement does not complete normally, |
| 5493 then, unless otherwise stated, the execution of $s$ stops |
| 5494 at that point and completes in the same way. |
| 5495 \commentary{ |
| 5496 For example, if execution of the body of a \DO{} loop returns a value, so does e
xecution of the \DO{} loop statement itself. |
| 5497 } |
| 5498 |
| 5499 If the execution of a statement is defined in terms of evaluating an expression |
| 5500 and the evaluation of that expression throws, |
| 5501 then, unless otherwise stated, the execution of the statement stops |
| 5502 at that point and throws the same exception object and stack trace. |
| 5503 \commentary{ |
| 5504 For example, if evaluation of the condition expression of an \IF{} statement thr
ows, |
| 5505 then so does execution of the \IF{} statement. Likewise, if evaluation of the ex
pression of a \RETURN{} statement throws, so does execution of the \RETURN{} sta
tement. |
| 5506 } |
| 5507 |
| 5508 \LMHash{} |
| 5509 |
5411 \begin{grammar} | 5510 \begin{grammar} |
5412 {\bf statements:} | 5511 {\bf statements:} |
5413 statement* | 5512 statement* |
5414 . | 5513 . |
5415 | 5514 |
5416 | 5515 |
5417 {\bf statement:} | 5516 {\bf statement:} |
5418 label* nonLabelledStatement | 5517 label* nonLabelledStatement |
5419 . | 5518 . |
5420 | 5519 |
(...skipping 14 matching lines...) Expand all Loading... |
5435 expressionStatement; | 5534 expressionStatement; |
5436 assertStatement; | 5535 assertStatement; |
5437 localFunctionDeclaration | 5536 localFunctionDeclaration |
5438 . | 5537 . |
5439 \end{grammar} | 5538 \end{grammar} |
5440 | 5539 |
5441 \subsection{Blocks} | 5540 \subsection{Blocks} |
5442 \LMLabel{blocks} | 5541 \LMLabel{blocks} |
5443 | 5542 |
5444 \LMHash{} | 5543 \LMHash{} |
5445 A {\em block statement} supports sequencing of code. | 5544 A {\em block statement} supports sequencing of code. |
5446 | 5545 |
5447 \LMHash{} | 5546 \LMHash{} |
5448 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: | 5547 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: |
5449 | 5548 |
5450 \LMHash{} | 5549 \LMHash{} |
5451 For $i \in 1 .. n, s_i$ is executed. | 5550 For $i \in 1 .. n, s_i$ is executed. |
5452 | 5551 |
5453 \LMHash{} | 5552 \LMHash{} |
5454 A block statement introduces a new scope, which is nested in the lexically enclo
sing scope in which the block statement appears. | 5553 A block statement introduces a new scope, which is nested in the lexically enclo
sing scope in which the block statement appears. |
5455 | 5554 |
5456 | 5555 |
5457 | 5556 \subsection{Expression Statements} |
5458 \subsection{Expression Statements} | 5557 \LMLabel{expressionStatements} |
5459 \LMLabel{expressionStatements} | |
5460 | 5558 |
5461 \LMHash{} | 5559 \LMHash{} |
5462 An {\em expression statement} consists of an expression other than a non-constan
t map literal (\ref{maps}) that has no explicit type arguments. | 5560 An {\em expression statement} consists of an expression other than a non-constan
t map literal (\ref{maps}) that has no explicit type arguments. |
5463 | 5561 |
5464 \rationale{ | 5562 \rationale{ |
5465 The restriction on maps is designed to resolve an ambiguity in the grammar, whe
n a statement begins with \{. | 5563 The restriction on maps is designed to resolve an ambiguity in the grammar, whe
n a statement begins with \{. |
5466 } | 5564 } |
5467 | 5565 |
5468 \begin{grammar} | 5566 \begin{grammar} |
5469 {\bf expressionStatement:} | 5567 {\bf expressionStatement:} |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5576 % elaborate on function identity and equality, runtime type. Likewsie in functio
n expressions (closures) and declarations | 5674 % elaborate on function identity and equality, runtime type. Likewsie in functio
n expressions (closures) and declarations |
5577 | 5675 |
5578 \subsection{If} | 5676 \subsection{If} |
5579 \LMLabel{if} | 5677 \LMLabel{if} |
5580 | 5678 |
5581 \LMHash{} | 5679 \LMHash{} |
5582 The {\em if statement} allows for conditional execution of statements. | 5680 The {\em if statement} allows for conditional execution of statements. |
5583 | 5681 |
5584 \begin{grammar} | 5682 \begin{grammar} |
5585 {\bf ifStatement:} | 5683 {\bf ifStatement:} |
5586 \IF{} `(' expression `)' statement ( \ELSE{} statement)? % we could allow
top level expression | 5684 \IF{} `(' expression `)' statement ( \ELSE{} statement)? |
5587 . | 5685 . |
5588 \end{grammar} | 5686 \end{grammar} |
5589 | 5687 |
5590 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{
\ELSE{} } $s_2$ proceeds as follows: | 5688 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{
\ELSE{} } $s_2$ proceeds as follows: |
5591 | 5689 |
5592 \LMHash{} | 5690 \LMHash{} |
5593 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. | 5691 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. |
5594 | |
5595 | 5692 |
5596 \commentary { | 5693 \commentary { |
5597 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv
alent to | 5694 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv
alent to |
5598 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ | 5695 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ |
5599 } | 5696 } |
5600 | 5697 |
5601 \rationale { | 5698 \rationale { |
5602 The reason for this equivalence is to catch errors such as | 5699 The reason for this equivalence is to catch errors such as |
5603 } | 5700 } |
5604 \begin{dartCode} | 5701 \begin{dartCode} |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5654 \end{grammar} | 5751 \end{grammar} |
5655 | 5752 |
5656 \LMHash{} | 5753 \LMHash{} |
5657 The for statement has three forms - the traditional for loop and two forms of t
he for-in statement - synchronous and asynchronous. | 5754 The for statement has three forms - the traditional for loop and two forms of t
he for-in statement - synchronous and asynchronous. |
5658 | 5755 |
5659 \subsubsection{For Loop} | 5756 \subsubsection{For Loop} |
5660 \LMLabel{forLoop} | 5757 \LMLabel{forLoop} |
5661 | 5758 |
5662 | 5759 |
5663 \LMHash{} | 5760 \LMHash{} |
5664 Execution of a for statement of the form \code{ \FOR{} (\VAR{} $v = e_0$ ; $c$
; $e$) $s$} proceeds as follows: | 5761 Execution of a for statement of the form \code{ \FOR{} (\VAR{} $v$ = $e_0$ ; $
c$; $e$) $s$} proceeds as follows: |
5665 | 5762 |
5666 \LMHash{} | 5763 \LMHash{} |
5667 If $c$ is empty then let $c^\prime$ be \TRUE{} otherwise let $c^\prime$ be $c$. | 5764 If $c$ is empty then let $c^\prime$ be \TRUE{} otherwise let $c^\prime$ be $c$. |
5668 | 5765 |
5669 \LMHash{} | 5766 \LMHash{} |
5670 First the variable declaration statement \VAR{} $v = e_0$ is executed. Then: | 5767 First the variable declaration statement \VAR{} $v = e_0$ is executed. Then: |
5671 \begin{enumerate} | 5768 \begin{enumerate} |
5672 \item | 5769 \item |
5673 \label{beginFor} | 5770 \label{beginFor} |
5674 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}. | 5771 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}. |
5675 \item | 5772 \item |
5676 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 | 5773 The expression $[v^\prime/v]c$ is evaluated and subjected to boolean conversion
(\ref{booleans}). If the result is \FALSE{}, the for loop completes normally. Ot
herwise, execution continues at step |
5677 \ref{beginIteration}. | 5774 \ref{beginIteration}. |
5678 \item | 5775 \item |
5679 \label{beginIteration} | 5776 \label{beginIteration} |
5680 The statement $[v^\prime/v]\{s\}$ is executed. | 5777 The statement $[v^\prime/v]\{s\}$ is executed. |
5681 \item | 5778 |
| 5779 If this execution completes normally, continues without a label, |
| 5780 or continues to a label (\ref{labels}) that prefixes this \FOR{} statement (\ref
{completion}), |
| 5781 then execution of the statement is treated as if it had completed normally. |
| 5782 |
5682 \label{allocateFreshVar} | 5783 \label{allocateFreshVar} |
5683 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the
value of $v^\prime$. | 5784 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the
value of $v^\prime$. |
5684 \item | 5785 \item |
5685 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at
step | 5786 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at
step |
5686 \ref{beginFor}. | 5787 \ref{beginFor}. |
5687 \end{enumerate} | 5788 \end{enumerate} |
5688 | 5789 |
5689 \rationale{ | 5790 \rationale{ |
5690 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. | 5791 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. |
5691 | 5792 |
(...skipping 23 matching lines...) Expand all Loading... |
5715 | 5816 |
5716 \begin{dartCode} | 5817 \begin{dartCode} |
5717 var n0 = $e$.iterator; | 5818 var n0 = $e$.iterator; |
5718 \WHILE{} (n0.moveNext()) \{ | 5819 \WHILE{} (n0.moveNext()) \{ |
5719 $finalConstVarOrType?$ id = n0.current; | 5820 $finalConstVarOrType?$ id = n0.current; |
5720 $s$ | 5821 $s$ |
5721 \} | 5822 \} |
5722 \end{dartCode} | 5823 \end{dartCode} |
5723 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$. | 5824 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$. |
5724 | 5825 |
5725 | |
5726 | |
5727 \subsubsection{Asynchronous For-in} | 5826 \subsubsection{Asynchronous For-in} |
5728 \LMLabel{asynchronousFor-in} | 5827 \LMLabel{asynchronousFor-in} |
5729 | 5828 |
5730 \LMHash{} | 5829 \LMHash{} |
5731 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. | 5830 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. |
5732 | 5831 |
5733 \LMHash{} | 5832 \LMHash{} |
5734 Execution of a for-in statement of the form \code{\AWAIT{} \FOR{} (finalConstVa
rOrType? id \IN{} $e$) $s$} proceeds as follows: | 5833 Execution of a for-in statement, $f$, of the form \code{\AWAIT{} \FOR{} (finalCo
nstVarOrType? $id$ \IN{} $e$) $s$} proceeds as follows: |
5735 | 5834 |
5736 \LMHash{} | 5835 \LMHash{} |
5737 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}. | 5836 The expression $e$ is evaluated to an object $o$. |
| 5837 It is a dynamic error if $o$ is not an instance of a class that implements \code
{Stream}. |
5738 | 5838 |
5739 \LMHash{} | 5839 \LMHash{} |
5740 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}). | 5840 The stream associated with the innermost enclosing asynchronous for loop, if any
, is paused. |
| 5841 The stream $o$ is listened to, producing a stream subscription $u$, |
| 5842 and execution of the asynchronous for-in loop is suspended |
| 5843 until a stream event is available. |
| 5844 \commentary{ |
| 5845 This allows other asynchronous events to execute while this loop is waiting for
stream events. |
| 5846 } |
| 5847 |
| 5848 Pausing an asynchronous for loop means pausing the associated stream subscriptio
n. |
| 5849 A stream subscription is paused by calling its \code{pause} method. |
| 5850 If the subscription is already paused, an implementation may omit further calls
to \code{pause}. |
| 5851 |
| 5852 \commentary{ |
| 5853 The \code{pause} call can throw, although that should never happen for a correct
ly implemented stream. |
| 5854 } |
5741 | 5855 |
5742 \LMHash{} | 5856 \LMHash{} |
5743 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. | 5857 For each {\em data event} from $u$, |
| 5858 the statement $s$ is executed with $id$ bound to the value of the current data e
vent. |
5744 | 5859 |
5745 \rationale{ | 5860 \LMHash{} |
5746 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. | 5861 \commentary{ |
| 5862 Either execution of $s$ is completely synchronous, or it contains an |
| 5863 asynchronous construct (\AWAIT{}, \AWAIT{} \FOR{}, \YIELD{} or \YIELD*) |
| 5864 which will pause the stream subscription of its surrounding asynchronous loop. |
| 5865 This ensures that no other event of $u$ occurs before execution of $s$ is comple
te, if $o$ is a correctly implemented stream. |
| 5866 If $o$ doesn't act as a valid stream, for example by not respecting pause reques
ts, the behavior of the asynchronous loop may become unpredictable. |
5747 } | 5867 } |
5748 | 5868 |
5749 \LMHash{} | 5869 \LMHash{} |
| 5870 If execution of $s$ continues without a label, or to a label (\ref{labels}) that
prefixes the asynchronous for statement (\ref{completion}), then the execution
of $s$ is treated as if it had completed normally. |
| 5871 |
| 5872 If execution of $s$ otherwise does not complete normally, the subscription $u$ i
s canceled by evaluating \code{\AWAIT{} $v$.cancel()} where $v$ is a fresh varia
ble referencing the stream subscription $u$. |
| 5873 If that evaluation throws, |
| 5874 execution of $f$ throws the same exception and stack trace. |
| 5875 Otherwise execution of $f$ completes in the same way as the execution of $s$. |
| 5876 % Notice: The previous specification was unclear about what happened when |
| 5877 % a subscripton is canceled. This text is explicit, and existing |
| 5878 % implementations may not properly await the cancel call. |
| 5879 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. |
| 5880 \commentary{ |
| 5881 The \code{resume} call can throw, in which case the asynchronous for |
| 5882 loop also throws. That should never happen for a correctly implemented stream. |
| 5883 } |
| 5884 |
| 5885 \LMHash{} |
| 5886 On an {\em error event} from $u$, |
| 5887 with error object $e$ and stack trace $st$, |
| 5888 the subscription $u$ is canceled by evaluating \code{\AWAIT{} v.cancel()} |
| 5889 where $v$ is a fresh variable referencing the stream subscription $u$. |
| 5890 If that evaluation throws, |
| 5891 execution of $f$ throws the same exception object and stack trace. |
| 5892 Otherwise execution of $f$ throws with $e$ as exception object and $st$ as stack
trace. |
| 5893 |
| 5894 \LMHash{} |
| 5895 When $u$ is done, execution of $f$ completes normally. |
| 5896 |
| 5897 \LMHash{} |
5750 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. | 5898 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. |
5751 | 5899 |
5752 \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.} | 5900 \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.} |
5753 | 5901 |
5754 | 5902 |
5755 \subsection{While} | 5903 \subsection{While} |
5756 \LMLabel{while} | 5904 \LMLabel{while} |
5757 | 5905 |
5758 \LMHash{} | 5906 \LMHash{} |
5759 The while statement supports conditional iteration, where the condition is evalu
ated prior to the loop. | 5907 The while statement supports conditional iteration, where the condition is evalu
ated prior to the loop. |
5760 | 5908 |
5761 \begin{grammar} | 5909 \begin{grammar} |
5762 {\bf whileStatement:} | 5910 {\bf whileStatement:} |
5763 \WHILE{} `(' expression `)' statement % could do top level here, and in f
or | 5911 \WHILE{} `(' expression `)' statement % could do top level here, and in f
or |
5764 . | 5912 . |
5765 \end{grammar} | 5913 \end{grammar} |
5766 | 5914 |
5767 \LMHash{} | 5915 \LMHash{} |
5768 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds
as follows: | 5916 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds a
s follows: |
5769 | 5917 |
5770 \LMHash{} | 5918 \LMHash{} |
5771 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. | 5919 The expression $e$ is evaluated to an object $o$. Then, $o$ is subjected to bool
ean conversion (\ref{booleanConversion}), producing an object $r$. |
| 5920 |
| 5921 \LMHash{} |
| 5922 If $r$ is \FALSE{}, then execution of the while statement completes normally |
| 5923 (\ref{completion}). |
| 5924 |
| 5925 \LMHash{} |
| 5926 Otherwise $r$ is \TRUE{} and then the statement $\{s\}$ is executed. |
| 5927 If that execution completes normally or it continues with no label or to a label
(\ref{labels}) that prefixes the \WHILE{} statement (\ref{completion}), then th
e while statement is re-executed. |
| 5928 If the execution breaks without a label, execution of the while statement comple
tes normally. |
| 5929 \commentary{ |
| 5930 If the execution breaks with a label that prefixes the \WHILE{} statement, |
| 5931 it does end execution of the loop, but the break itself is handled by the surrou
nding labeled statement (\ref{labels}). |
| 5932 } |
5772 | 5933 |
5773 \LMHash{} | 5934 \LMHash{} |
5774 It is a static type warning if the static type of $e$ may not be assigned to \co
de{bool}. | 5935 It is a static type warning if the static type of $e$ may not be assigned to \co
de{bool}. |
5775 | 5936 |
5776 | 5937 |
5777 \subsection{Do} | 5938 \subsection{Do} |
5778 \LMLabel{do} | 5939 \LMLabel{do} |
5779 | 5940 |
5780 \LMHash{} | 5941 \LMHash{} |
5781 The do statement supports conditional iteration, where the condition is evaluate
d after the loop. | 5942 The do statement supports conditional iteration, where the condition is evaluate
d after the loop. |
5782 | 5943 |
5783 \begin{grammar} | 5944 \begin{grammar} |
5784 {\bf doStatement:} | 5945 {\bf doStatement:} |
5785 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t
op level here | 5946 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t
op level here |
5786 . | 5947 . |
5787 \end{grammar} | 5948 \end{grammar} |
5788 | 5949 |
5789 | 5950 |
5790 \LMHash{} | 5951 \LMHash{} |
5791 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed
s as follows: | 5952 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed
s as follows: |
5792 | 5953 |
5793 \LMHash{} | 5954 \LMHash{} |
5794 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. | 5955 The statement $\{s\}$ is executed. |
| 5956 If that execution continues with no label, or to a label (\ref{labels}) that pre
fixes the do statement (\ref{completion}), then the execution of $s$ is treated
as if it had completed normally. |
| 5957 |
| 5958 \LMHash{} |
| 5959 Then, the expression $e$ is evaluated to an object $o$. Then, $o$ is subjected t
o boolean conversion (\ref{booleanConversion}), producing an object $r$. |
| 5960 If $r$ is \FALSE{}, execution of the do statement completes normally (\ref{compl
etion}). |
| 5961 If $r$ is \TRUE{}, then the do statement is re-executed. |
5795 | 5962 |
5796 \LMHash{} | 5963 \LMHash{} |
5797 It is a static type warning if the static type of $e$ may not be assigned to \co
de{bool}. | 5964 It is a static type warning if the static type of $e$ may not be assigned to \co
de{bool}. |
5798 | 5965 |
5799 \subsection{Switch} | 5966 \subsection{Switch} |
5800 \LMLabel{switch} | 5967 \LMLabel{switch} |
5801 | 5968 |
5802 \LMHash{} | 5969 \LMHash{} |
5803 The {\em switch statement} supports dispatching control among a large number of
cases. | 5970 The {\em switch statement} supports dispatching control among a large number of
cases. |
5804 | 5971 |
5805 \begin{grammar} | 5972 \begin{grammar} |
5806 {\bf switchStatement:} | 5973 {\bf switchStatement:} |
5807 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do
top level here and in cases | 5974 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do
top level here and in cases |
5808 . | 5975 . |
5809 | 5976 |
5810 | 5977 |
5811 {\bf switchCase:} | 5978 {\bf switchCase:} |
5812 label* \CASE{} expression `{\escapegrammar :}' statements | 5979 label* \CASE{} expression `{\escapegrammar :}' statements |
5813 . | 5980 . |
5814 | 5981 |
5815 {\bf defaultCase:} | 5982 {\bf defaultCase:} |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5879 \SWITCH{} ($e$) \{ | 6046 \SWITCH{} ($e$) \{ |
5880 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 6047 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5881 $\ldots$ | 6048 $\ldots$ |
5882 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 6049 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5883 \} | 6050 \} |
5884 \end{dartCode} | 6051 \end{dartCode} |
5885 | 6052 |
5886 proceeds as follows: | 6053 proceeds as follows: |
5887 | 6054 |
5888 \LMHash{} | 6055 \LMHash{} |
5889 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$. | 6056 The statement \code{\VAR{} $id$ = $e$;} is evaluated, where $id$ is a fresh vari
able. In checked mode, it is a run time error if the value of $e$ is not an inst
ance of the same class as the constants $e_1 \ldots e_n$. |
5890 | 6057 |
5891 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do
es not matter.} | 6058 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do
es not matter.} |
5892 | 6059 |
5893 \LMHash{} | 6060 \LMHash{} |
5894 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}$. | 6061 Next, the case clause \CASE{} $e_{1}$: $s_{1}$ is matched against $id$, if $n >
0$. Otherwise if there is a \DEFAULT{} clause, the case statements $s_{n+1}$ are
executed (\ref{case-execute}). |
5895 | 6062 |
5896 \LMHash{} | 6063 \LMHash{} |
5897 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. | 6064 Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5898 | |
5899 \LMHash{} | |
5900 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | |
5901 | 6065 |
5902 \begin{dartCode} | 6066 \begin{dartCode} |
5903 \SWITCH{} ($e$) \{ | 6067 \SWITCH{} ($e$) \{ |
5904 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 6068 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5905 $\ldots$ | 6069 $\ldots$ |
5906 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 6070 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5907 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ | 6071 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
5908 \} | 6072 \} |
5909 \end{dartCode} | 6073 \end{dartCode} |
5910 | 6074 |
5911 proceeds as follows: | 6075 against the value of a variable $id$ proceeds as follows: |
5912 | 6076 |
5913 \LMHash{} | 6077 \LMHash{} |
5914 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su
bjected to boolean conversion yielding a value $v$. | 6078 The expression \code{$e_k$ == $id$} is evaluated to an object $o$ which is then
subjected to boolean conversion evaluating to a value $v$. |
5915 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}$. | 6079 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched
against $id$ if $k < n$. If $k = n$, then the \DEFAULT{} clause's statements are
executed (\ref{case-execute}). |
5916 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. | 6080 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 case statements $s_h$
are then executed (\ref{case-execute}). |
5917 If execution reaches the point after $s_h$ then a runtime error occurs, unless
$h = n+1$. | |
5918 | 6081 |
5919 \LMHash{} | 6082 \LMHash{} |
5920 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement | 6083 Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement |
5921 | 6084 |
5922 \begin{dartCode} | 6085 \begin{dartCode} |
5923 \SWITCH{} ($e$) \{ | 6086 \SWITCH{} ($e$) \{ |
5924 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ | 6087 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
5925 $\ldots$ | 6088 $\ldots$ |
5926 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ | 6089 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
5927 \} | 6090 \} |
5928 \end{dartCode} | 6091 \end{dartCode} |
5929 | 6092 |
5930 proceeds as follows: | 6093 against the value of a variable $id$ proceeds as follows: |
5931 | 6094 |
5932 \LMHash{} | 6095 \LMHash{} |
5933 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su
bjected to boolean conversion yielding a value $v$. | 6096 The expression \code{$e_k$ == $id$} is evaluated to an object $o$ which is then
subjected to boolean conversion evaluating to a value $v$. |
5934 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut
ed if it exists. | 6097 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched
against $id$ if $k < n$. |
5935 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. | 6098 If $v$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_h$
is non-empty. If such a $h$ exists, the case statements $s_h$ are executed (\re
f{case-execute}). Otherwise the switch statement completes normally ( |
5936 If execution reaches the point after $s_h$ then a runtime error occurs, unless
$h = n$. | 6099 ref{completion}). |
5937 | 6100 |
5938 | 6101 |
5939 \commentary{ | |
5940 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. | |
5941 } | |
5942 | |
5943 \LMHash{} | 6102 \LMHash{} |
5944 It is a static warning if the type of $e$ may not be assigned to the type of $e_
k$. | 6103 It is a static warning if the type of $e$ may not be assigned to the type of $e_
k$. |
5945 Let $s$ be the last statement of the statement sequence $s_k$. | 6104 Let $s$ be the last statement of the statement sequence $s_k$. |
5946 If $s$ is a non-empty block statement, let $s$ instead be the last statment of t
he block statement. | 6105 If $s$ is a non-empty block statement, let $s$ instead be the last statement of
the block statement. |
5947 It is a static warning $s$ is not a \BREAK{}, \CONTINUE{}, \RETHROW{} or \RETURN
{} statement or an expression statment where the expression is a \THROW{} expres
sion. | 6106 It is a static warning $s$ is not a \BREAK{}, \CONTINUE{}, \RETHROW{} or \RETURN
{} statement or an expression statement where the expression is a \THROW{} expre
ssion. |
5948 | 6107 |
5949 \rationale{ | 6108 \rationale{ |
5950 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)
. | 6109 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)
. |
5951 | 6110 |
5952 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.: | 6111 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.: |
5953 } | 6112 } |
5954 | 6113 |
5955 \begin{dartCode} | 6114 \begin{dartCode} |
5956 \SWITCH{} (x) \{ | 6115 \SWITCH{} (x) \{ |
5957 \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN{};\} \FINALLY{} \{ $\ldots$ \RETURN{};\} | 6116 \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN{};\} \FINALLY{} \{ $\ldots$ \RETURN{};\} |
5958 \} | 6117 \} |
5959 \end{dartCode} | 6118 \end{dartCode} |
5960 | 6119 |
5961 \rationale{ | 6120 \rationale{ |
5962 Very elaborate code in a case clause is probably bad style in any case, and su
ch code can always be refactored. | 6121 Very elaborate code in a case clause is probably bad style in any case, and su
ch code can always be refactored. |
5963 } | 6122 } |
5964 | 6123 |
5965 \LMHash{} | 6124 \LMHash{} |
5966 It is a static warning if all of the following conditions hold: | 6125 It is a static warning if all of the following conditions hold: |
5967 \begin{itemize} | 6126 \begin{itemize} |
5968 \item The switch statement does not have a default clause. | 6127 \item The switch statement does not have a default clause. |
5969 \item The static type of $e$ is an enumerated typed with elements $id_1, \ldots
, id_n$. | 6128 \item The static type of $e$ is an enumerated typed with elements $id_1, \ldots
, id_n$. |
5970 \item The sets $\{e_1, \ldots, e_k\} $ and $\{id_1, \ldots, id_n\}$ are not the
same. | 6129 \item The sets $\{e_1, \ldots, e_k\} $ and $\{id_1, \ldots, id_n\}$ are not the
same. |
5971 \end{itemize} | 6130 \end{itemize} |
5972 | 6131 |
5973 \commentary{ | 6132 \commentary{ |
5974 In other words, a warning will be issued if a switch statement over an enum is n
ot exhaustive. | 6133 In other words, a warning will be issued if a switch statement over an enum is n
ot exhaustive. |
5975 } | 6134 } |
5976 | 6135 |
| 6136 \LMHash{} |
| 6137 \subsubsection{Switch case statements} |
| 6138 \LMLabel{case-execute} |
| 6139 |
| 6140 \LMHash{} |
| 6141 Execution of the case statements $s_h$ of a switch statement |
| 6142 |
| 6143 \begin{dartCode} |
| 6144 \SWITCH{} ($e$) \{ |
| 6145 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
| 6146 $\ldots$ |
| 6147 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
| 6148 \} |
| 6149 \end{dartCode} |
| 6150 |
| 6151 or a switch statement |
| 6152 |
| 6153 \begin{dartCode} |
| 6154 \SWITCH{} ($e$) \{ |
| 6155 $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$ |
| 6156 $\ldots$ |
| 6157 $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ |
| 6158 $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$ |
| 6159 \} |
| 6160 \end{dartCode} |
| 6161 |
| 6162 proceeds as follows: |
| 6163 |
| 6164 \LMHash{} |
| 6165 Execute $\{s_h\}$. |
| 6166 If this execution completes normally, |
| 6167 and if $s_h$ is not the statements of the last case of the switch |
| 6168 ($h = n$ if there is no \DEFAULT{} clause, |
| 6169 $h = n+1$ if there is a \DEFAULT{} clause), |
| 6170 then the execution of the switch case throws an error. |
| 6171 Otherwise $s_h$ are the last statements of the switch case, |
| 6172 and execution of the switch case completes normally. |
| 6173 |
| 6174 \commentary{ |
| 6175 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. |
| 6176 } |
| 6177 |
| 6178 If execution of $\{s_h\}$ breaks with no label (\ref{completion}), then the exec
ution of the switch statement completes normally. |
| 6179 |
| 6180 If execution of $\{s_h\}$ continues to a label (\ref{completion}), and the label
is $label_{ij}$, where $1 \le i \le n+1$ if the \SWITCH{} statement has a \DEFA
ULT{}, or $1 \le i \le n$ if there is no \DEFAULT{}, and where $1 \le j \le j_{i
}$, then |
| 6181 let $h$ be the smallest number such that $h \ge i$ and $s_h$ is non-empty. If no
such $h$ exists, let $h = n + 1$ if the \SWITCH{} statement has a \DEFAULT{}, o
therwise let $h = n$. |
| 6182 The case statements $s_h$ are then executed (\ref{case-execute}). |
| 6183 |
| 6184 If execution of $\{s_h\}$ completes in any other way, execution of the \SWITCH{}
statement completes in the same way. |
| 6185 |
5977 | 6186 |
5978 \subsection{ Rethrow} | 6187 \subsection{ Rethrow} |
5979 \LMLabel{rethrow} | 6188 \LMLabel{rethrow} |
5980 | 6189 |
5981 | 6190 |
5982 \LMHash{} | 6191 \LMHash{} |
5983 The {\em rethrow statement} is used to re-raise an exception. | 6192 The {\em rethrow statement} is used to re-throw an exception and its associated
stack trace. |
5984 | 6193 |
5985 \begin{grammar} | 6194 \begin{grammar} |
5986 {\bf rethrowStatement:} | 6195 {\bf rethrowStatement:} |
5987 \RETHROW{} `{\escapegrammar ;}' | 6196 \RETHROW{} `{\escapegrammar ;}' |
5988 . | 6197 . |
5989 \end{grammar} | 6198 \end{grammar} |
5990 | 6199 |
5991 \LMHash{} | 6200 \LMHash{} |
5992 Execution of a \code{\RETHROW{}} statement proceeds as follows: | 6201 Execution of a \code{\RETHROW{}} statement proceeds as follows: |
5993 | 6202 |
5994 \LMHash{} | 6203 \LMHash{} |
5995 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}). | 6204 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}). |
5996 | 6205 |
5997 \rationale{ | 6206 \rationale{ |
5998 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. | 6207 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. |
5999 } | 6208 } |
6000 | 6209 |
6001 \LMHash{} | 6210 \LMHash{} |
6002 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$. | 6211 The \RETHROW{} statement {\em throws} (\ref{completion}) with $p_1$ as the excep
tion object and $p_2$ as the stack trace. |
6003 | |
6004 \LMHash{} | |
6005 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. | |
6006 | |
6007 \rationale{ | |
6008 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. | |
6009 } | |
6010 | |
6011 \LMHash{} | |
6012 Otherwise, control is transferred to the innermost enclosing exception handler. | |
6013 | |
6014 \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.} | |
6015 | 6212 |
6016 \LMHash{} | 6213 \LMHash{} |
6017 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit
hin an \ON-\CATCH{} clause. | 6214 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit
hin an \ON-\CATCH{} clause. |
6018 | 6215 |
6019 | 6216 |
6020 | |
6021 \subsection{ Try} | 6217 \subsection{ Try} |
6022 \LMLabel{try} | 6218 \LMLabel{try} |
6023 | 6219 |
6024 \LMHash{} | 6220 \LMHash{} |
6025 The try statement supports the definition of exception handling code in a struct
ured way. | 6221 The try statement supports the definition of exception handling code in a struct
ured way. |
6026 | 6222 |
6027 \begin{grammar} | 6223 \begin{grammar} |
6028 {\bf tryStatement:} | 6224 {\bf tryStatement:} |
6029 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) | 6225 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) |
6030 . | 6226 . |
6031 | 6227 |
6032 {\bf onPart:}catchPart block; | 6228 {\bf onPart:}catchPart block; |
6033 \ON{} type catchPart? block | 6229 \ON{} type catchPart? block |
6034 . | 6230 . |
6035 | 6231 |
6036 {\bf catchPart:} | 6232 {\bf catchPart:} |
6037 \CATCH{} `(' identifier (`,' identifier)? `)' | 6233 \CATCH{} `(' identifier (`,' identifier)? `)' |
6038 . | 6234 . |
6039 | 6235 |
6040 {\bf finallyPart:} | 6236 {\bf finallyPart:} |
6041 \FINALLY{} block | 6237 \FINALLY{} block |
6042 . | 6238 . |
6043 \end{grammar} | 6239 \end{grammar} |
6044 | 6240 |
6045 \LMHash{} | 6241 \LMHash{} |
6046 A try statement consists of a block statement, followed by at least one of: | 6242 A try statement consists of a block statement, followed by at least one of: |
6047 \begin{enumerate} | 6243 \begin{enumerate} |
6048 \item | 6244 \item |
6049 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. | 6245 A set of \ON{}-\CATCH{} clauses, each of which specifies (either explicitly or i
mplicitly) the type of exception object to be handled, one or two exception para
meters, and a block statement. |
6050 \item | 6246 \item |
6051 A \FINALLY{} clause, which consists of a block statement. | 6247 A \FINALLY{} clause, which consists of a block statement. |
6052 \end{enumerate} | 6248 \end{enumerate} |
6053 | 6249 |
6054 \rationale{ | 6250 \rationale{ |
6055 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. | 6251 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. |
6056 } | 6252 } |
6057 | 6253 |
6058 \LMHash{} | 6254 \LMHash{} |
6059 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. | |
6060 | |
6061 \commentary { | |
6062 It is of course a static warning if $T$ is a deferred or malformed type. | |
6063 } | |
6064 | |
6065 \LMHash{} | |
6066 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}. | |
6067 | |
6068 | |
6069 \LMHash{} | |
6070 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. | |
6071 | |
6072 | |
6073 \LMHash{} | |
6074 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$}. | |
6075 | |
6076 | |
6077 %If an explicit type is associated with of $p_2$, it is a static warning if that
type is not \code{Object} or \DYNAMIC{}. | |
6078 | |
6079 \LMHash{} | |
6080 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. | |
6081 %\begin{enumerate} | |
6082 %\item Started execution after the currently executing function. | |
6083 %\item Had not completed execution at the point where the exception caught by th
e currently executing \ON{}-\CATCH{} clause was initially thrown. | |
6084 %\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.} | |
6085 %\end{enumerate} | |
6086 | |
6087 \commentary{ | |
6088 This implies that no synthetic function activations may be added to the trace, n
or may any source level activations be omitted. | |
6089 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. | |
6090 | |
6091 Nothing is said about how any native function calls may be represented in the tr
ace. | |
6092 } | |
6093 | |
6094 \commentary{ | |
6095 Note that we say nothing about the identity of the stack trace, or what notion o
f equality is defined for stack traces. | |
6096 } | |
6097 | |
6098 % 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 | |
6099 % 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. | |
6100 | |
6101 % 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. | |
6102 | |
6103 % Is this controversial? We were thinking of viewing the trace as a List<Invoca
tion>, | |
6104 % 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. | |
6105 | |
6106 \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. } | |
6107 | |
6108 % A position can be represented via a Token. If we make that part of the core r
eflection facility, we can state this here. | |
6109 | |
6110 \LMHash{} | |
6111 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: | |
6112 | |
6113 \LMHash{} | |
6114 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. | |
6115 | |
6116 | |
6117 \LMHash{} | |
6118 A finally clause \FINALLY{} $s$ defines an exception handler $h$ that executes a
s follows: | |
6119 | |
6120 \LMHash{} | |
6121 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. | |
6122 | |
6123 \rationale{ | |
6124 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. | |
6125 } | |
6126 | |
6127 \LMHash{} | |
6128 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: | |
6129 \begin{itemize} | |
6130 \item | |
6131 if there is a dynamically enclosing error handler $g$ defined by a \FINALLY{} c
lause in $m$, control is transferred to $g$. | |
6132 \item | |
6133 Otherwise $m$ terminates. | |
6134 \end{itemize} | |
6135 | |
6136 Otherwise, execution resumes at the end of the try statement. | |
6137 | |
6138 \LMHash{} | |
6139 Execution of an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} $
s$ of a try statement $t$ proceeds as follows: | |
6140 The statement $s$ is executed in the dynamic scope of the exception handler defi
ned by the finally clause of $t$. Then, the current exception and active stack t
race both become undefined. | |
6141 | |
6142 \LMHash{} | |
6143 Execution of a \FINALLY{} clause \FINALLY{} $s$ of a try statement proceeds as f
ollows: | |
6144 | |
6145 \LMHash{} | |
6146 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. | |
6147 | |
6148 | |
6149 \LMHash{} | |
6150 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: | |
6151 | |
6152 \LMHash{} | |
6153 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. | |
6154 | |
6155 \commentary{ | |
6156 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). | |
6157 | |
6158 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
. | |
6159 | |
6160 If a matching \ON{}-\CATCH{} was found, it will execute first, and then the \FIN
ALLY{} clause will be executed. | |
6161 | |
6162 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. | |
6163 | |
6164 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. | |
6165 } | |
6166 | |
6167 \LMHash{} | |
6168 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{} $\{\}$}. | 6255 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{} $\{\}$}. |
6169 | 6256 |
| 6257 \LMHash{} |
| 6258 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 a fresh identifier. |
| 6259 |
| 6260 \LMHash{} |
| 6261 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$ a
nd $p_2$ are fresh identifiers. |
| 6262 |
| 6263 \LMHash{} |
| 6264 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 a fresh identifier. |
| 6265 |
| 6266 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p_1$, $p_2$) $s$} is equiv
alent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1$, $p_2$)
$s$}. |
| 6267 |
| 6268 \LMHash{} |
| 6269 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 t
ype of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}. |
| 6270 |
| 6271 \LMHash{} |
| 6272 Execution of a \TRY{} statement $s$ on the form: |
| 6273 \begin{dartCode} |
| 6274 \TRY{} $b$ |
| 6275 \ON{} $T_1$ \CATCH{} ($e_1$, $t_1$) $c_1$ |
| 6276 \ldots{} |
| 6277 \ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) $c_n$ |
| 6278 \FINALLY{} $f$ |
| 6279 \end{dartCode} |
| 6280 proceeds as follows: |
| 6281 |
| 6282 \LMHash{} |
| 6283 First $b$ is executed. |
| 6284 If execution of $b$ throws (\ref{completion}) with exception object $e$ and stac
k trace $t$, then $e$ and $t$ are matched against the \ON{}-\CATCH{} clauses to
yield a new completion (\ref{on-catch}). |
| 6285 |
| 6286 Then, even if execution of $b$ did not complete normally or matching against the
\ON{}-\CATCH{} clauses did not complete normally, the $f$ block is executed. |
| 6287 |
| 6288 If execution of $f$ does not complete normally, |
| 6289 execution of the \TRY{} statement completes in the same way. |
| 6290 Otherwise if execution of $b$ threw (\ref{completion}), the \TRY{} statement com
pletes in the same way as the matching against the \ON{}-\CATCH{} clauses. |
| 6291 Otherwise the \TRY{} statement completes in the same way as the execution of $b$
. |
| 6292 |
| 6293 \LMHash{} |
| 6294 If $T_1$ is a malformed or deferred type (\ref{staticTypes}), then performing a
match causes a run time error. |
| 6295 It is a static warning if $T_i$, $1 \le i \le n$ is a deferred or malformed type
. |
| 6296 |
| 6297 \subsubsection{\ON{}-\CATCH{} clauses} |
| 6298 \LMLabel{on-catch} |
| 6299 |
| 6300 \LMHash{} |
| 6301 Matching an exception object $e$ and stack trace $t$ against a (potentially empt
y) sequence of \ON{}-\CATCH{} clauses on the form |
| 6302 \begin{dartCode} |
| 6303 \ON{} $T_1$ \CATCH{} ($e_1$, $st_1$) \{ $s_1$ \} |
| 6304 \ldots |
| 6305 \ON{} $T_n$ \CATCH{} ($e_n$, $st_n$) \{ $s_n$ \} |
| 6306 \end{dartCode} |
| 6307 proceeds as follows: |
| 6308 |
| 6309 \LMHash{} |
| 6310 If there are no \ON{}-\CATCH{} clauses ($n = 0$), matching throws the exception
object $e$ and stack trace $t$ (\ref{completion}). |
| 6311 |
| 6312 \LMHash{} |
| 6313 Otherwise the exception is matched against the first clause. |
| 6314 |
| 6315 \LMHash{} |
| 6316 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. |
| 6317 The matching completes in the same way as this execution. |
| 6318 |
| 6319 \LMHash{} |
| 6320 Otherwise, if the first clause did not match $e$, $e$ and $t$ are recursively ma
tched against the remaining \ON{}-\CATCH{} clauses: |
| 6321 \begin{dartCode} |
| 6322 \ON{} $T_2$ \CATCH{} ($e_2$, $t_2$) \{ $s_2$ \} |
| 6323 \ldots |
| 6324 \ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) \{ $s_n$ \} |
| 6325 \end{dartCode} |
| 6326 |
6170 | 6327 |
6171 \subsection{ Return} | 6328 \subsection{ Return} |
6172 \LMLabel{return} | 6329 \LMLabel{return} |
6173 | 6330 |
6174 \LMHash{} | 6331 \LMHash{} |
6175 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}). | 6332 The {\em return statement} returns a result to the caller of a synchronous funct
ion, completes the future associated with an asynchronous function or terminates
the stream or iterable associated with a generator (\ref{functions}). |
6176 | 6333 |
6177 | 6334 |
6178 \begin{grammar} | 6335 \begin{grammar} |
6179 {\bf returnStatement:} | 6336 {\bf returnStatement:} |
6180 \RETURN{} expression? `{\escapegrammar ;}' % could do top level here | 6337 \RETURN{} expression? `{\escapegrammar ;}' % could do top level here |
6181 . | 6338 . |
6182 \end{grammar} | 6339 \end{grammar} |
6183 | 6340 |
6184 \commentary{ | |
6185 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. | |
6186 } | |
6187 | |
6188 \LMHash{} | |
6189 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. | |
6190 | |
6191 \LMHash{} | 6341 \LMHash{} |
6192 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows: | 6342 Executing a return statement \code{\RETURN{} $e$;} proceeds as follows: |
6193 | 6343 |
6194 \LMHash{} | 6344 \LMHash{} |
6195 First the expression $e$ is evaluated, producing an object $o$. Next: | 6345 First the expression $e$ is evaluated, producing an object $o$. |
6196 \begin{itemize} | 6346 Then the return statement returns the value $o$ (\ref{completion}). |
6197 \item | |
6198 The current return value is set to $o$ and the current exception (\ref{throw}) a
nd active stack trace (\ref{try}) become undefined. | |
6199 \item | |
6200 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$. | |
6201 \item | |
6202 Otherwise execution of the current method terminates. | |
6203 \end{itemize} | |
6204 | |
6205 \commentary{ | |
6206 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}. | |
6207 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. | |
6208 } | |
6209 | 6347 |
6210 \LMHash{} | 6348 \LMHash{} |
6211 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct
ion. | 6349 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct
ion. |
6212 | 6350 |
6213 \LMHash{} | 6351 \LMHash{} |
6214 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$ ma
y not be assigned to the declared return type of $f$. | 6352 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$ ma
y not be assigned to the declared return type of $f$. |
6215 | 6353 |
6216 \LMHash{} | 6354 \LMHash{} |
6217 Let $S$ be the runtime type of $o$. In checked mode: | 6355 Let $S$ be the runtime type of $o$. In checked mode: |
6218 \begin{itemize} | 6356 \begin{itemize} |
(...skipping 23 matching lines...) Expand all Loading... |
6242 \end{itemize} | 6380 \end{itemize} |
6243 | 6381 |
6244 \commentary{ | 6382 \commentary{ |
6245 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 function
that declares a return type must return an expression explicitly. | 6383 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 function
that declares a return type must return an expression explicitly. |
6246 } | 6384 } |
6247 \rationale{This helps catch situations where users forget to return a value in a
return statement.} | 6385 \rationale{This helps catch situations where users forget to return a value in a
return statement.} |
6248 | 6386 |
6249 \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 wel
l, but any other type will cause a warning, since \NULL{} has no subtypes.} | 6387 \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 wel
l, but any other type will cause a warning, since \NULL{} has no subtypes.} |
6250 | 6388 |
6251 \LMHash{} | 6389 \LMHash{} |
6252 A return statement with no expression, \code{\RETURN;} is executed as follows: | 6390 Executing a return statement with no expression, \code{\RETURN;} returns with no
value (\ref{completion}). |
6253 | 6391 |
6254 \LMHash{} | |
6255 If the immediately enclosing function $f$ is a generator, then: | |
6256 \begin{itemize} | |
6257 \item | |
6258 The current return value is set to \NULL{}. | |
6259 \item | |
6260 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$. | |
6261 \item | |
6262 Otherwise, execution of the current method terminates. | |
6263 \end{itemize} | |
6264 | |
6265 \LMHash{} | |
6266 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{};}. | |
6267 | |
6268 \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{};} | |
6269 %in a \VOID{} function; neither is it illegal | |
6270 in a generative constructor. The rules relate only to the specific syntactic for
m \code{\RETURN{} $e$;}. | |
6271 } | |
6272 | |
6273 | |
6274 \rationale{ | |
6275 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. | |
6276 | |
6277 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. | |
6278 } | |
6279 | 6392 |
6280 \LMHash{} | 6393 \LMHash{} |
6281 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$;}. | 6394 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$;}. |
6282 | 6395 |
6283 | 6396 |
6284 | |
6285 | |
6286 \subsection{ Labels} | 6397 \subsection{ Labels} |
6287 \LMLabel{labels} | 6398 \LMLabel{labels} |
6288 | 6399 |
6289 \LMHash{} | 6400 \LMHash{} |
6290 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$. | 6401 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$. |
6291 | 6402 |
6292 \rationale{The sole role of labels is to provide targets for the break (\ref{bre
ak}) and continue (\ref{continue}) statements.} | 6403 \rationale{The sole role of labels is to provide targets for the break (\ref{bre
ak}) and continue (\ref{continue}) statements.} |
6293 | 6404 |
6294 %\Q{Are labels in a separate namespace? Bug 49774299} | 6405 %\Q{Are labels in a separate namespace? Bug 49774299} |
6295 | 6406 |
6296 \begin{grammar} | 6407 \begin{grammar} |
6297 {\bf label:} | 6408 {\bf label:} |
6298 identifier `{\escapegrammar :}' | 6409 identifier `{\escapegrammar :}' |
6299 . | 6410 . |
6300 \end{grammar} | 6411 \end{grammar} |
6301 | 6412 |
6302 \LMHash{} | 6413 \LMHash{} |
6303 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. | 6414 Execution a labeled statement $s$, $label: s_l$, consists of executing $s_l$. |
| 6415 If execution of $s_l$ breaks to the label $label$ (\ref{completion}), |
| 6416 then execution of $s$ completes normally, |
| 6417 otherwise execution of $s$ completes in the same ways as the execution of $s_l$. |
| 6418 |
| 6419 \LMHash{} |
| 6420 The namespace of labels is distinct from the one used for types, functions and v
ariables. |
6304 | 6421 |
6305 \LMHash{} | 6422 \LMHash{} |
6306 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$. | 6423 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$. |
6307 | 6424 |
6308 \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. | 6425 \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. |
6309 } | 6426 } |
6310 | 6427 |
6311 | 6428 |
6312 \subsection{ Break} | 6429 \subsection{ Break} |
6313 \LMLabel{break} | 6430 \LMLabel{break} |
6314 | 6431 |
6315 \LMHash{} | 6432 \LMHash{} |
6316 The {\em break statement} consists of the reserved word \BREAK{} and an optional
label (\ref{labels}). | 6433 The {\em break statement} consists of the reserved word \BREAK{} and an optional
label (\ref{labels}). |
6317 | 6434 |
6318 \begin{grammar} | 6435 \begin{grammar} |
6319 {\bf breakStatement:} | 6436 {\bf breakStatement:} |
6320 \BREAK{} identifier? `{\escapegrammar ;}' | 6437 \BREAK{} identifier? `{\escapegrammar ;}' |
6321 . | 6438 . |
6322 \end{grammar} | 6439 \end{grammar} |
6323 | 6440 |
6324 \LMHash{} | 6441 \LMHash{} |
6325 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$. | 6442 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. |
6326 | 6443 |
6327 \LMHash{} | 6444 \LMHash{} |
6328 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}$. | 6445 Execution of a \BREAK{} statement \code{\BREAK{} $L$;} breaks to the label $L$ (
\ref{completion}). |
6329 | 6446 |
| 6447 Execution of a \BREAK{} statement \code{\BREAK{};} breaks without a label (\ref{
completion}). |
6330 | 6448 |
6331 | 6449 |
6332 \subsection{ Continue} | 6450 \subsection{ Continue} |
6333 \LMLabel{continue} | 6451 \LMLabel{continue} |
6334 | 6452 |
6335 \LMHash{} | 6453 \LMHash{} |
6336 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op
tional label (\ref{labels}). | 6454 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op
tional label (\ref{labels}). |
6337 | 6455 |
6338 \begin{grammar} | 6456 \begin{grammar} |
6339 {\bf continueStatement:} | 6457 {\bf continueStatement:} |
6340 \CONTINUE{} identifier? `{\escapegrammar ;}' | 6458 \CONTINUE{} identifier? `{\escapegrammar ;}' |
6341 . | 6459 . |
6342 \end{grammar} | 6460 \end{grammar} |
6343 | 6461 |
6344 \LMHash{} | 6462 \LMHash{} |
6345 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. | 6463 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. |
6346 | 6464 |
6347 \commentary{ | 6465 Execution of a \CONTINUE{} statement \code{\CONTINUE{} $L$;} continues to the la
bel $L$ (\ref{completion}). |
6348 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. | 6466 |
6349 } | 6467 Execution of a \CONTINUE{} statement \code{\CONTINUE{};} continues without a lab
el (\ref{completion}). |
| 6468 |
| 6469 |
| 6470 \subsection{ Yield and Yield-Each} |
| 6471 \LMLabel{yieldAndYieldEach} |
| 6472 |
| 6473 \subsubsection{ Yield} |
| 6474 \LMLabel{yield} |
6350 | 6475 |
6351 \LMHash{} | 6476 \LMHash{} |
6352 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}$. | 6477 The {\em yield statement} adds an element to the result of a generator function
(\ref{functions}). |
6353 | 6478 |
6354 \subsection{ Yield and Yield-Each} | 6479 \begin{grammar} |
6355 \LMLabel{yieldAndYieldEach} | |
6356 | |
6357 \subsubsection{ Yield} | |
6358 \LMLabel{yield} | |
6359 | |
6360 \LMHash{} | |
6361 The {\em yield statement} adds an element to the result of a generator function
(\ref{functions}). | |
6362 | |
6363 \begin{grammar} | |
6364 {\bf yieldStatement:} | 6480 {\bf yieldStatement:} |
6365 \YIELD{} expression `{\escapegrammar ;}' | 6481 \YIELD{} expression `{\escapegrammar ;}' |
6366 . | 6482 . |
6367 \end{grammar} | 6483 \end{grammar} |
6368 | 6484 |
6369 \LMHash{} | 6485 \LMHash{} |
6370 Execution of a statement $s$ of the form \code{\YIELD{} $e$;} proceeds as follo
ws: | 6486 Execution of a statement $s$ of the form \code{\YIELD{} $e$;} proceeds as follo
ws: |
6371 | 6487 |
6372 \LMHash{} | 6488 \LMHash{} |
6373 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. | 6489 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. |
6374 | 6490 |
6375 \LMHash{} | 6491 \LMHash{} |
6376 Next, $o$ is added to the iterable or stream associated with the immediately enc
losing function. | 6492 Next, $o$ is added to the iterable or stream associated with the immediately enc
losing function. |
6377 | 6493 |
6378 \LMHash{} | 6494 \LMHash{} |
6379 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. | 6495 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi
th $m$ has been canceled, then the \YIELD{} statement returns without a value (\
ref{completion}), otherwise it completes normally. |
6380 | 6496 |
6381 \rationale{ | 6497 \rationale{ |
6382 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. | 6498 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. |
6383 } | 6499 } |
6384 | 6500 |
6385 \LMHash{} | 6501 \LMHash{} |
6386 Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) the
n the enclosing function may suspend. | 6502 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. |
6387 | 6503 |
6388 \rationale { | 6504 \rationale { |
6389 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. | 6505 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. |
6390 } | 6506 } |
6391 | 6507 |
6392 | 6508 |
6393 \LMHash{} | 6509 \LMHash{} |
6394 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: | 6510 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: |
6395 \begin{itemize} | 6511 \begin{itemize} |
6396 \item | 6512 \item |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6429 | 6545 |
6430 \LMHash{} | 6546 \LMHash{} |
6431 First, the expression $e$ is evaluated to an object $o$. | 6547 First, the expression $e$ is evaluated to an object $o$. |
6432 | 6548 |
6433 \LMHash{} | 6549 \LMHash{} |
6434 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th
en: | 6550 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th
en: |
6435 \begin{enumerate} | 6551 \begin{enumerate} |
6436 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl
e}. Otherwise | 6552 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl
e}. Otherwise |
6437 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$. | 6553 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$. |
6438 \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 | 6554 \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 |
6439 \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$. | 6555 \item The getter \cd{current} is invoked on $i$. If the invocation throws (\ref{
evaluation}), execution of $s$ throws the same exception object and stack trace
(\ref{completion}). Otherwise, the result $x$ of the getter invocation is added
to the iterable associated with $m$. |
6440 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}. | 6556 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}. |
6441 \item | 6557 \item |
6442 The current call to \code{moveNext()} returns \TRUE. | 6558 The current call to \code{moveNext()} returns \TRUE. |
6443 \end{enumerate} | 6559 \end{enumerate} |
6444 | 6560 |
6445 \LMHash{} | 6561 \LMHash{} |
6446 If $m$ is marked \ASYNC* (\ref{functions}), then: | 6562 If $m$ is marked \ASYNC* (\ref{functions}), then: |
6447 \begin{itemize} | 6563 \begin{itemize} |
6448 \item It is a dynamic error if the class of $o$ does not implement \code{Stream
}. Otherwise | 6564 \item It is a dynamic error if the class of $o$ does not implement \code{Stream
}. Otherwise |
6449 \item For each element $x$ of $o$: | 6565 \item The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), if
any, is paused. |
| 6566 \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$: |
6450 \begin{itemize} | 6567 \begin{itemize} |
6451 \item | 6568 \item |
6452 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is
suspended until $u$ is resumed or canceled. | 6569 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is
suspended until $u$ is resumed or canceled. |
6453 \item | |
6454 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. | |
6455 \item | 6570 \item |
6456 Otherwise, $x$ is added to the stream associated with $m$ in the order it appea
rs in $o$. The function $m$ may suspend. | 6571 If the stream $u$ associated with $m$ has been canceled, |
| 6572 then $s$ is canceled by evaluating \code{\AWAIT{} v.cancel()} where $v$ is a fre
sh variable referencing the stream subscription $s$. |
| 6573 Then, if the cancel completed normally, the stream execution of $s$ returns with
out a value (\ref{completion}). |
| 6574 \item |
| 6575 Otherwise, $x$, or $e$ with $t$, are added to the stream associated with $m$ in
the order they appear in $o$. The function $m$ may suspend. |
6457 \end{itemize} | 6576 \end{itemize} |
6458 \item If the stream $o$ is done, execution of $s$ is complete. | 6577 \item If the stream $o$ is done, execution of $s$ completes normally. |
6459 \end{itemize} | 6578 \end{itemize} |
6460 | 6579 |
6461 | 6580 |
6462 \LMHash{} | 6581 \LMHash{} |
6463 It is a compile-time error if a yield-each statement appears in a function that
is not a generator function. | 6582 It is a compile-time error if a yield-each statement appears in a function that
is not a generator function. |
6464 | 6583 |
6465 \LMHash{} | 6584 \LMHash{} |
6466 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}. | 6585 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}. |
6467 | 6586 |
6468 | 6587 |
6469 \subsection{ Assert} | 6588 \subsection{ Assert} |
6470 \LMLabel{assert} | 6589 \LMLabel{assert} |
6471 | 6590 |
6472 \LMHash{} | 6591 \LMHash{} |
6473 An {\em assert statement} is used to disrupt normal execution if a given boolean
condition does not hold. | 6592 An {\em assert statement} is used to disrupt normal execution if a given boolean
condition does not hold. |
6474 | 6593 |
6475 \begin{grammar} | 6594 \begin{grammar} |
6476 {\bf assertStatement:} | 6595 {\bf assertStatement:} |
6477 assert `(' expression `)' `{\escapegrammar ;}' | 6596 assert `(' expression `)' `{\escapegrammar ;}' |
6478 . | 6597 . |
6479 \end{grammar} | 6598 \end{grammar} |
6480 | 6599 |
6481 \LMHash{} | 6600 \LMHash{} |
6482 The assert statement has no effect in production mode. In checked mode, executio
n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: | 6601 The assert statement has no effect in production mode. In checked mode, executio
n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: |
6483 | 6602 |
6484 \LMHash{} | 6603 \LMHash{} |
6485 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$. | 6604 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$. |
6486 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. | 6605 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 throws (\ref{completion}) an \code{AssertionErro
r} with a stack trace corresponding to the current execution state at the \ASSER
T{} statement. |
6487 | 6606 |
6488 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion
Error();\}} (in checked mode only). | 6607 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion
Error();\}} (in checked mode only). |
6489 %What about an error message as part of the assert?} | 6608 %What about an error message as part of the assert?} |
6490 | 6609 |
6491 \LMHash{} | 6610 \LMHash{} |
6492 It is a static type warning if the type of $e$ may not be assigned to either \
code{bool} or $() \rightarrow$ \code{bool}. | 6611 It is a static type warning if the type of $e$ may not be assigned to either \
code{bool} or $() \rightarrow$ \code{bool}. |
6493 | 6612 |
6494 \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. | 6613 \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. |
6495 } | 6614 } |
6496 | 6615 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6643 | 6762 |
6644 \rationale{ | 6763 \rationale{ |
6645 One cannot detect the problem at compile time because compilation often occurs
during execution and one does not know what the URI refers to. However the dev
elopment environment should detect the problem. | 6764 One cannot detect the problem at compile time because compilation often occurs
during execution and one does not know what the URI refers to. However the dev
elopment environment should detect the problem. |
6646 } | 6765 } |
6647 | 6766 |
6648 | 6767 |
6649 \LMHash{} | 6768 \LMHash{} |
6650 The {\em current library} is the library currently being compiled. The import mo
difies the namespace of the current library in a manner that is determined by t
he imported library and by the optional elements of the import. | 6769 The {\em current library} is the library currently being compiled. The import mo
difies the namespace of the current library in a manner that is determined by t
he imported library and by the optional elements of the import. |
6651 | 6770 |
6652 \LMHash{} | 6771 \LMHash{} |
6653 An immediate import directive $I$ may optionally include a prefix clause of the
form \AS{} \code{Id} used to prefix names imported by $I$. A deferred import mus
t include a prefix clause or a compile time error occurs. It is a compile-time e
rror if a prefix used in a deferred import is used in another import clause. | 6772 An immediate import directive $I$ may optionally include a prefix clause of the
form \code{\AS{} $id$} used to prefix names imported by $I$. A deferred import m
ust include a prefix clause or a compile time error occurs. It is a compile-time
error if a prefix used in a deferred import is used in another import clause. |
6654 | 6773 |
6655 \LMHash{} | 6774 \LMHash{} |
6656 An import directive $I$ may optionally include a namespace combinator clauses us
ed to restrict the set of names imported by $I$. Currently, two namespace combin
ators are supported: \HIDE{} and \SHOW{}. | 6775 An import directive $I$ may optionally include a namespace combinator clauses us
ed to restrict the set of names imported by $I$. Currently, two namespace combin
ators are supported: \HIDE{} and \SHOW{}. |
6657 | 6776 |
6658 \LMHash{} | 6777 \LMHash{} |
6659 Let $I$ be an import directive that refers to a URI via the string $s_1$. Evalua
tion of $I$ proceeds as follows: | 6778 Let $I$ be an import directive that refers to a URI via the string $s_1$. Evalua
tion of $I$ proceeds as follows: |
6660 | 6779 |
6661 \LMHash{} | 6780 \LMHash{} |
6662 If $I$ is a deferred import, no evaluation takes place. Instead, a mapping of th
e name of the prefix, $p$ to a {\em deferred prefix object} is added to the scop
e of the current library $L$. | 6781 If $I$ is a deferred import, no evaluation takes place. Instead, a mapping of th
e name of the prefix, $p$ to a {\em deferred prefix object} is added to the scop
e of the current library $L$. |
6663 The deferred prefix object has the following methods: | 6782 The deferred prefix object has the following methods: |
(...skipping 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7887 | 8006 |
7888 The invariant that each normative paragraph is associated with a line | 8007 The invariant that each normative paragraph is associated with a line |
7889 containing the text \LMHash{} should be maintained. Extra occurrences | 8008 containing the text \LMHash{} should be maintained. Extra occurrences |
7890 of \LMHash{} can be added if needed, e.g., in order to make | 8009 of \LMHash{} can be added if needed, e.g., in order to make |
7891 individual \item{}s in itemized lists addressable. Each \LM.. command | 8010 individual \item{}s in itemized lists addressable. Each \LM.. command |
7892 must occur on a separate line. \LMHash{} must occur immediately | 8011 must occur on a separate line. \LMHash{} must occur immediately |
7893 before the associated paragraph, and \LMLabel must occur immediately | 8012 before the associated paragraph, and \LMLabel must occur immediately |
7894 after the associated \section{}, \subsection{} etc. | 8013 after the associated \section{}, \subsection{} etc. |
7895 | 8014 |
7896 ---------------------------------------------------------------------- | 8015 ---------------------------------------------------------------------- |
OLD | NEW |