OLD | NEW |
(Empty) | |
| 1 \documentclass{article} |
| 2 \usepackage{epsfig} |
| 3 \usepackage{dart} |
| 4 \usepackage{bnf} |
| 5 \usepackage{hyperref} |
| 6 \newcommand{\code}[1]{{\sf #1}} |
| 7 \title{Dart Programming Language Specification \\ |
| 8 {\large Draft Version 0.61}} |
| 9 \author{The Dart Team} |
| 10 \begin{document} |
| 11 \maketitle |
| 12 |
| 13 \tableofcontents |
| 14 |
| 15 \newpage |
| 16 |
| 17 \pagestyle{myheadings} |
| 18 \markright{{\bf Draft} Dart Programming Language Specification {\bf Draft}} |
| 19 |
| 20 \section{Notes} |
| 21 |
| 22 Expect the contents and language rules to change over time. |
| 23 %Please mail comments to gbracha@google.com. |
| 24 |
| 25 \subsection{Licensing} |
| 26 \label{licensing} |
| 27 |
| 28 |
| 29 Except as otherwise noted at http://code.google.com/policies.html\#restrictions,
the content of this document is licensed under the Creative Commons Attribution
3.0 License available at: |
| 30 |
| 31 http://creativecommons.org/licenses/by/3.0/ |
| 32 |
| 33 and code samples are licensed under the BSD license available at |
| 34 |
| 35 http://code.google.com/google\_bsd\_license.html. |
| 36 |
| 37 \subsection{Change Log} |
| 38 \label{changes} |
| 39 |
| 40 \subsubsection{Changes Since Version 0.02} |
| 41 |
| 42 The following changes have been made in version 0.03 since version 0.02. In addi
tion, various typographical errors have been corrected. The changes are listed b
y section number. |
| 43 |
| 44 \ref{notation}: Expanded examples of grammar. |
| 45 |
| 46 \ref{factories}: Corrected reference to undefined production {\em typeVariables}
to {\em typeParameters}. |
| 47 |
| 48 \ref{superinterfaces}: Removed static warning when imported superinterface of a
class contains private members. |
| 49 |
| 50 The former section on factories and constructors in interfaces (now removed): Re
moved redundant prohibition on default values. |
| 51 |
| 52 \ref{interfaceSuperinterfaces}: Removed static warning when imported superinterf
ace of an interface contains private members. |
| 53 |
| 54 \ref{expressions}: Fixed typo in grammar. |
| 55 |
| 56 \ref{new}, \ref{const} : made explicit accessibility requirement for class being
constructed. |
| 57 |
| 58 \ref{const}: make clear that referenced constructor must be marked \CONST{}. |
| 59 |
| 60 \ref{superInvocation}: fixed botched sentence where superclass $S$ is introduced
. |
| 61 |
| 62 \ref{postfixExpressions}: qualified definition of $v++$ so it is clear that $v$
is an identifier. |
| 63 |
| 64 |
| 65 |
| 66 \subsubsection{Changes Since Version 0.03} |
| 67 |
| 68 \ref{instanceMethods}. The former section on interface methods (now removed): Ad
ded missing requirement that overriding methods have same number of required par
ameters and all optional parameters as overridden method, in same order. |
| 69 |
| 70 \ref{generics}: Added prohibition against cyclic type hierarchy for type parame
ters. |
| 71 |
| 72 \ref{instanceCreation}: Clarified requirements on use of parameterized types in
instance creation expressions. |
| 73 |
| 74 \ref{bindingActualsToFormals}: Added requirement that $q_i$ are distinct. |
| 75 |
| 76 \ref{staticInvocation}. Static method invocation determines the function (which
may involve evaluating a getter) before evaluating the arguments, so that static
invocation and top-level function invocation agree. |
| 77 |
| 78 \ref{typeTest}: Added missing test that type being tested against is in scope an
d is indeed a type. |
| 79 |
| 80 \ref{forLoop}: Changed for loop to introduce fresh variable for each iteration. |
| 81 |
| 82 \ref{parameterizedTypes}: Malformed parameterized types generate warnings, not e
rrors(except when used in reified contexts like instance creation and superclass
es/interfaces). |
| 83 |
| 84 |
| 85 \subsubsection{Changes Since Version 0.04} |
| 86 |
| 87 Added hyperlinks in PDF. |
| 88 |
| 89 \ref{operators}: Removed unary plus operator. Clarified that operator formals mu
st be required. |
| 90 |
| 91 \ref{constantConstructors}: Filled in a lot of missing detail. |
| 92 |
| 93 The former section on factories and constructors in interfaces (now removed): Al
lowed factory class to be declared via a qualified name. |
| 94 |
| 95 \ref{numbers}: Changed production for $Number$. |
| 96 |
| 97 \ref{const}: Added requirements that actuals be constant, rules for dealing with
inappropriate types of actuals, and examples. Also explicitly prohibit type par
ameters. |
| 98 |
| 99 \ref{functionExpressionInvocation}: Modified final bullet to keep it inline with
similar clauses in other sections. Exact wording of these sections also tweaked
slightly. |
| 100 |
| 101 \ref{unaryExpressions}: Specified ! operator. Eliminated section on prefix expr
essions and moved contents to section on unary expressions. |
| 102 |
| 103 \ref{lexicalRules}: Specified unicode form of Dart source. |
| 104 |
| 105 |
| 106 \subsubsection{Changes Since Version 0.05} |
| 107 |
| 108 \ref{generativeConstructors}: Clarified how initializing formals can act as opti
onal parameters of generative constructors. |
| 109 |
| 110 \ref{factories}: Treat factories as constructors, so type parameters are implici
tly in scope. |
| 111 |
| 112 The former section on factories and constructors in interfaces (now removed): Si
mplify rules for interface factory clauses. Use the keyword \DEFAULT{} instead o
f \FACTORY{}. |
| 113 |
| 114 \ref{generics}: Mention that typedefs can have type parameters. |
| 115 |
| 116 \ref{typeTest}: Added checked mode test that type arguments match generic type. |
| 117 |
| 118 \ref{dynamicTypeSystem}: Added definition of malformed types, and requirement on
their handling in checked mode. |
| 119 |
| 120 \subsubsection{Changes Since Version 0.06} |
| 121 |
| 122 \ref{variables}: library variable initializers must be constant. |
| 123 |
| 124 \ref{classes}: Added \ABSTRACT{} modifier to grammar. |
| 125 |
| 126 \ref{classes}, \ref{staticMethods}, \ref{staticVariables}, \ref{unqualifiedInvoc
ation},\ref{identifierReference}: Superclass static members are not in scope in
subclasses, and do not conflict with subclass members. |
| 127 |
| 128 \ref{operators}: \code{[]=} must return \VOID{}. Operator \CALL{} added to supp
ort function emulation. Removed operator \code{$>>>$}. Made explicit restriction
on methods named \CALL{} or \NEGATE{}. |
| 129 |
| 130 \ref{constants}: Added \code{!$e$} as constant expression. Clarified what happen
s if evaluation of a constant fails. |
| 131 |
| 132 \ref{maps}: Map keys need not be constants. However, they are always string lite
rals. |
| 133 |
| 134 \ref{this}: State restrictions on use of \THIS{}. |
| 135 |
| 136 \ref{instanceCreation}, \ref{new}: Rules for bounds checking of constructor argu
ments when calling default constructors for interfaces refined. |
| 137 |
| 138 \ref{ordinaryInvocation}: Revised semantics to account for function emulation. |
| 139 |
| 140 \ref{staticInvocation}: Revised semantics to account for function emulation. |
| 141 |
| 142 \ref{superInvocation}: Factory constructors cannot contain super invocations. Re
vised semantics to account for function emulation. |
| 143 |
| 144 \ref{assignment}: Specified assignment involving \code{[]=} operator. |
| 145 |
| 146 \ref{compoundAssignment}: Removed operator \code{$>>>$}. |
| 147 |
| 148 \ref{shift}: Removed operator \code{$>>>$}. |
| 149 |
| 150 \ref{postfixExpressions}: Postfix \code{-{}-} operator specified. Behavior of p
ostfix operations on subscripted expressions specified. |
| 151 |
| 152 \ref{identifierReference}: Added built-in identifier \CALL{}. Banned use of bui
lt-in identifiers as types made other uses warnings. |
| 153 |
| 154 \ref{typeTest}: Moved specification of test that type arguments match generic ty
pe to \ref{dynamicTypeSystem}. |
| 155 |
| 156 \ref{switch}: Corrected evaluation of case clauses so that case expression is th
e receiver of ==. Revised specification to correctly deal with blank statement
s in case clauses. |
| 157 |
| 158 \ref{assert}: Fixed bug in \ASSERT{} specification that could lead to puzzlers. |
| 159 |
| 160 \ref{dynamicTypeSystem}: Consolidated definition of malformed types. |
| 161 |
| 162 \ref{functionTypes}: Revised semantics to account for function emulation. |
| 163 |
| 164 |
| 165 \subsubsection{Changes Since Version 0.07} |
| 166 |
| 167 \ref{variables}: Static variables are lazily initialized, but need not be consta
nts. Orthogonal notion of constant variable introduced. |
| 168 |
| 169 \ref{operators}: Added \EQUALS{} operator as part of revised \code{==} treatment
. |
| 170 |
| 171 \ref{generativeConstructors}: Initializing formals have the same type as the fie
ld they correspond to. |
| 172 |
| 173 \ref{staticVariables}: Static variable getter rules revised to deal with lazy in
itialization. |
| 174 |
| 175 \ref{expressions}: Modified syntax to support cascaded method invocations. |
| 176 |
| 177 \ref{constants}: Removed support for + operator on Strings. Extended string co
nstants to support certain cases of string interpolation. Revised constants to d
eal with constant variables. |
| 178 |
| 179 \ref{strings}: Corrected definition of \code{HEX\_DIGIT\_SEQUENCE}. Support impl
icit concatenation of adjacent single line strings. |
| 180 |
| 181 \ref{bindingActualsToFormals}: Centralized and corrected type rules for function
invocation. |
| 182 |
| 183 \ref{methodInvocation}: Moved rules for checking function/method invocations to
\ref{bindingActualsToFormals}. Added definition of cascaded method invocations. |
| 184 |
| 185 \ref{getterInvocation}, \ref{assignment}: Updated \code{noSuchMethod()} call for
getters and setters to conform to planned API. |
| 186 |
| 187 \ref{conditional}: Modified syntax to support cascaded method invocations. |
| 188 |
| 189 \ref{equality}: Revised semantics for \code{==}. |
| 190 |
| 191 \ref{identifierReference}: Removed \IMPORT{}, \LIBRARY{} and \SOURCE{} from list
of built-in identifiers and added \EQUALS{}. Revised rules for evaluating ident
ifiers to deal with lazy static variable initialization. |
| 192 |
| 193 \ref{continue}: Fixed bug that allowed \CONTINUE{} labeled on non-loops. |
| 194 |
| 195 \ref{librariesAndScripts}: Revised syntax so no space is permitted between \code
{\#} and directives. Introduced \code{show:} combinator. Describe \code{prefix:}
as a combinator. Added initial discussion of namespaces. Preclude string interp
olation in arguments to directives. |
| 196 |
| 197 \subsubsection{Changes Since Version 0.08} |
| 198 |
| 199 \ref{instanceMethods}, \ref{abstractInstanceMembers}: Abstract methods may speci
fy default values. |
| 200 |
| 201 \ref{interfaces}, The former section on interface methods (now removed): Interfa
ce methods may specify default values. |
| 202 |
| 203 \ref{constants}: The \code{\~{}/ } operator can apply to doubles. |
| 204 |
| 205 \ref{instanceCreation}: Refined rules regarding abstract class instantiation, al
lowing factories to be used. |
| 206 |
| 207 \ref{switch}: \SWITCH{} statement specification revised. |
| 208 |
| 209 \ref{throw}: \THROW{} may not throw \NULL{}. |
| 210 |
| 211 \ref{imports}: Imports introduce a scope separate from the library scope. Multip
le libraries may share prefix. |
| 212 |
| 213 \ref{typedef}: Recursive typedefs disallowed. |
| 214 |
| 215 \subsubsection{Changes Since Version 0.09} |
| 216 |
| 217 \ref{scoping}: Consolidated discussion of namespaces and scopes. Started to tigh
ten up definitions of scopes. |
| 218 |
| 219 \ref{classes}: Overriding of fields allowed. |
| 220 |
| 221 \ref{operators}: \CALL{} is no longer an operator. |
| 222 |
| 223 The former section on variables in interfaces (now removed): Added specification
of variable declarations in interfaces. |
| 224 |
| 225 \ref{constants}: Static methods and top-level functions are compile-time constan
ts. |
| 226 |
| 227 \ref{strings}: Multiline strings can be implicitly concatenated and contain inte
rpolated expressions. |
| 228 |
| 229 \ref{typeCast}: Type cast expression added. |
| 230 |
| 231 \ref{expressionStatements}: Map literals cannot be expression statements. |
| 232 |
| 233 \ref{try}, \ref{throw}: Clarified type of stack trace. |
| 234 |
| 235 \ref{exports}, \ref{imports}: Added re-export facility. |
| 236 |
| 237 |
| 238 \subsubsection{Changes Since Version 0.10} |
| 239 |
| 240 \ref{overview}: Discuss reified runtime types. |
| 241 |
| 242 \ref{scoping}: Removed shadowing warnings. Allow overloading of \code{-}. |
| 243 |
| 244 \ref{variables}: Centralized discussion of implicit getters and setters. |
| 245 |
| 246 \ref{externalFunctions}: External functions added. |
| 247 |
| 248 \ref{classes}: Abstract classes must now be declared explicitly. |
| 249 |
| 250 \ref{operators}: Eliminate \NEGATE{} in favor of overloaded unary minus. Elimina
te \EQUALS{} in favor of operator \code{==}. |
| 251 |
| 252 \ref{setters}: Setter syntax no longer includes = sign after the name. |
| 253 |
| 254 \ref{abstractInstanceMembers}: Clarify that getters and setters may be abstrac
t. Eliminate \ABSTRACT{} modifier for abstract members. Added static warning if
abstract class has abstract member. |
| 255 |
| 256 \ref{instanceVariables}: Instance variables can be initialized to non-constants.
Moved discussion of implicit getters and setters to \ref{variables}. |
| 257 |
| 258 \ref{generativeConstructors}: Clarify that finals can only be set once. |
| 259 |
| 260 \ref{redirectingFactoryConstructors}: Added redirecting factories. |
| 261 |
| 262 \ref{staticVariables}: Moved discussion of implicit getters and setters to \ref{
variables}. |
| 263 |
| 264 \ref{interfaces}: Eliminated interface declarations. |
| 265 |
| 266 \ref{metadata}: Added metadata. |
| 267 |
| 268 \ref{constants}: Refined definition constant identity/caching. |
| 269 |
| 270 \ref{throw}: Stack traces moved to \ref{try}. |
| 271 |
| 272 \ref{new}: Creating an instance via \NEW{} using an undefined class or construct
or is a dynamic error and a static warning, not a compile-time error. Evaluatio
n rules to allow instance variables with non-constant initializers. Instantiati
ng an abstract class via a generative constructor is now a dynamic error. |
| 273 |
| 274 \ref{equality}: Replaced \code{===} with built-in function \code{identical()}. E
quality does not special case identity. |
| 275 |
| 276 \ref{identifierReference}: Type names have meaning as expressions. \ASSERT{} is
not a built-in identifier anymore, but \EXPORT{}, \IMPORT{}, \LIBRARY{} and \PAR
T{} are. Removed warning on use of built-in identifiers as variable/function nam
es. |
| 277 |
| 278 \ref{typeCast}: type cast accepts \NULL{}. |
| 279 |
| 280 \ref{argumentDefinitionTest}: Added operation to determine if optional argument
was actually passed. |
| 281 |
| 282 \ref{localFunctionDeclaration}: Added section on local functions. |
| 283 |
| 284 \ref{switch}: Allow switch on compile-time constants of any one type. |
| 285 |
| 286 \ref{try}: Revised syntax for \CATCH{} clauses. Specification of stack traces mo
ved from \ref{throw}. |
| 287 |
| 288 \ref{return}: Made explicit that checked mode tests returns. |
| 289 |
| 290 \ref{assert}: \ASSERT{} is now a reserved word. |
| 291 |
| 292 \ref{librariesAndScripts}: Revised library syntax and semantics. |
| 293 |
| 294 \ref{typeDynamic}: Renamed {\bf Dynamic} to \DYNAMIC{}. |
| 295 |
| 296 \ref{reservedWords}: \ASSERT{} is a reserved word. |
| 297 |
| 298 |
| 299 \subsubsection{Changes Since Version 0.11} |
| 300 |
| 301 \ref{notation}: Moved discussion of tokenization to section \ref{reference}. |
| 302 |
| 303 \ref{numbers}: Removed unary plus. |
| 304 |
| 305 \ref{librariesAndScripts}: Refined definition of show and hide to handle getters
and setters in pairs. |
| 306 |
| 307 \ref{functionTypes}: All function types are subtypes of \code{Function}. |
| 308 |
| 309 \ref{reference}: Added discussion of tokenization. |
| 310 |
| 311 \ref{reservedWords}: Defined meaning of reserved word. |
| 312 |
| 313 \ref{comments}: Added initial discussion of dartdoc comments. |
| 314 |
| 315 \subsubsection{Changes Since Version 0.12} |
| 316 |
| 317 \ref{classes}: Removed \ABSTRACT{} modifier from grammar of members. Added gramm
ar for \WITH{} clause. |
| 318 |
| 319 \ref{superclasses}: Added discussion of new \WITH{} clause for mixins. |
| 320 |
| 321 \ref{mixins}: Added specification of mixins. |
| 322 |
| 323 \ref{constants}: Revised description of \code{identical()} so that it always ret
urns \TRUE{} on numbers with the same class and value. |
| 324 |
| 325 \ref{null}: Invocations on \NULL{} throw \code{NoSuchMethodError} only. |
| 326 |
| 327 \ref{throw}: \THROW{} of \NULL{} raises \code{NullThrownError}. |
| 328 |
| 329 \ref{instanceCreation} Using undefined types as type arguments to a constructor
is a dynamic failure. |
| 330 |
| 331 \ref{librariesAndScripts}: Added discussion of compilation units. Allow name cl
ause to be optional for libraries, allow export clauses in scripts. Support full
y qualified name for libraries. Allow different imports to share same prefix. Ad
ded mixin application as a top level declaration. |
| 332 |
| 333 \ref{typedef}: Typedefs for mixin applications added. |
| 334 |
| 335 \ref{interfaceTypes}: Add effects of mixin clause on subtyping. |
| 336 |
| 337 \ref{leastUpperBounds}: Corrected definition of LUBs. |
| 338 |
| 339 \ref{reservedWords}: Added keyword \WITH{}. |
| 340 |
| 341 |
| 342 \subsubsection{Changes Since Version 0.20} |
| 343 |
| 344 \ref{getters}: Getters cannot return \VOID{}. |
| 345 |
| 346 \ref{superinterfaces}: Added requirement that superclass cannot appear in \IMPLE
MENTS{} clause. |
| 347 |
| 348 \ref{interfaceInheritanceAndOverriding}: Clarified status of getter/setter vs. m
ethod conflicts in multiple interface inheritance. |
| 349 |
| 350 \ref{throw}: Separated \THROW{} into \code{\THROW{} e} and \code{\RETHROW{}}. |
| 351 |
| 352 \ref{new}: Arguments to constructor are evaluated before allocating new object. |
| 353 |
| 354 \ref{unqualifiedInvocation}: Calling an undeclared method in a static context is
a dynamic error (and a static warning) not a compile-time one. |
| 355 |
| 356 \ref{ordinaryInvocation}, \ref{superInvocation}, \ref{getterInvocation}, \ref{as
signment}: Refined description of \code{InvocationMirror} instance passed to \co
de{noSuchMethod()}. |
| 357 |
| 358 \ref{lexicalRules}: Abandoned requirement for Unicode Normalization Form C. |
| 359 |
| 360 \subsubsection{Changes Since Version 0.30} |
| 361 |
| 362 \ref{superclasses}, \ref{superinterfaces}: Clarified that super types with wrong
number of type arguments cause a compilation error. |
| 363 |
| 364 \subsubsection{Changes Since Version 0.31} |
| 365 |
| 366 \ref{abstractInstanceMembers}: Abstract methods act as pure declarations. |
| 367 |
| 368 \ref{mixins}: Mixin application has forwarding constructors for all superclass c
onstructors. |
| 369 |
| 370 \ref{instanceCreation}, \ref{new}: Revised so that wrong generic arity is a runt
ime error with static warning. |
| 371 |
| 372 \ref{typeTest}, \ref{typeCast}: Eliminated special treatment of malformed types
. |
| 373 |
| 374 \ref{rethrow}: Rethrow is a statement, not an expression. |
| 375 |
| 376 \ref{librariesAndScripts}: Semicolon required after top-level external declarati
ons. |
| 377 |
| 378 \ref{imports}: Removed requirement that library names be unique within an isolat
e. |
| 379 |
| 380 \ref{dynamicTypeSystem}: Revised definition of malformed types. Revised behavior
of checked and production modes wrt to malformed and malbounded types. Refined
assignability rules wrt new function type subtyping. |
| 381 |
| 382 \ref{interfaceTypes}: Corrected oversight wrt type variables and \cd{Object}. |
| 383 |
| 384 \ref{functionTypes}: Liberalized function subtyping rules. Special assignability
rules. |
| 385 |
| 386 \ref{parameterizedTypes}: Out with misconstructed types, in with malbounded ones
. |
| 387 |
| 388 \subsubsection{Changes Since Version 0.40} |
| 389 |
| 390 \ref{expressions}: Argument definition test construct dropped. |
| 391 |
| 392 \ref{maps}: Map literals can be keyed by arbitrary expressions. |
| 393 |
| 394 \ref{librariesAndScripts}: Implicitly named libraries are named `'. Script tags
are allowed in all libraries. It is a warning to import or export two libraries
with the same name. |
| 395 |
| 396 \subsubsection{Changes Since Version 0.41} |
| 397 |
| 398 \ref{variables}: Uninitialized final is now just a static warning. |
| 399 |
| 400 \ref{typeOfAFunction}: Added details about the run time type of functions. |
| 401 |
| 402 \ref{instanceVariables}: Disallowed const inst vars. |
| 403 |
| 404 \ref{redirectingConstructors}: Uninitialized final is now just a static warning. |
| 405 |
| 406 \ref{objectIdentity}, \ref{constants}: Clarified rules for double identity. |
| 407 |
| 408 \ref{maps}: Adjusted rules for constant map literals. |
| 409 |
| 410 \ref{propertyExtraction}: If the same method is extracted repeatedly from the sa
me object, the results are equal. Furthermore, the type of the property extract
ion is based on the method being closurized. Also described handling of propert
y extractions on \SUPER{} explicitly. |
| 411 |
| 412 \ref{getterInvocation}: Explicitly described getter invocations on \SUPER{}. |
| 413 |
| 414 \subsubsection{Changes Since Version 0.50} |
| 415 |
| 416 % there was no public 0.50! |
| 417 |
| 418 \ref{variables}: Final variables introduce setters that trap on execution. Not i
nitializing a final is a warning, not an error. Initializing a final variable d
eclared with an initializer is a warning, not an error. |
| 419 |
| 420 \ref{requiredFormals}: Initializing formals can specify function types. These m
ay not specify defaults. |
| 421 |
| 422 \ref{instanceMethods}: Corrected override rules to fit with earlier relaxation o
f function subtype rules. Furthermore, bad overrides provoke warnings not errors
. Also, methods and corresponding setters yield warnings. |
| 423 |
| 424 \ref{generativeConstructors}: Initializing a final variable declared with an in
itializer is a warning, not an error. |
| 425 |
| 426 \ref{staticMethods}: Corresponding setters yield warnings. |
| 427 |
| 428 \ref{inheritanceAndOverriding}: Refined definitions of inheritance and overridin
g to correctly account for library privacy. |
| 429 |
| 430 \ref{superinterfaces}: Suppress type warnings for unimplemented members of super
interfaces if the class declares \code{noSuchMethod()}. |
| 431 |
| 432 \ref{interfaceInheritanceAndOverriding}: Refined definitions of inheritance and
overriding to correctly account for library privacy. |
| 433 |
| 434 \ref{constants}: Literal symbols are constants. |
| 435 |
| 436 \ref{numbers}, \ref{booleans}, \ref{strings}: Specified the runtime type of numb
ers, booleans and strings. |
| 437 |
| 438 \ref{strings}: Implicit concatenation works among all kinds of strings. |
| 439 |
| 440 \ref{symbols}: Added literal symbols. |
| 441 |
| 442 \ref{if}, \ref{for}, \ref{while}, \ref{do}: Single statements in control constru
cts implicitly introduce a block. |
| 443 |
| 444 \ref{imports}: Introduced special treatment for imports conflicts with \code{dar
t:core}. Ambiguous names are treated as malformed types or \code{NoSuchMethodErr
or}s. |
| 445 |
| 446 \ref{typedef}: Tightened restrictions on recursive typedefs. |
| 447 |
| 448 %\ref{typeDynamic}: Clarified that \DYNAMIC{} is not an expression. |
| 449 |
| 450 \subsubsection{Changes Since Version 0.51} |
| 451 |
| 452 \ref{classes}: Mixin applications are a kind of class definition. |
| 453 |
| 454 \ref{generativeConstructors}: Clarify that executing repeated initialization of
a final variable by an initializer or initializing formal is a run-time error. |
| 455 |
| 456 \ref{mixins}: Mixin applications are defined using \CLASS{} rather than \TYPED
EF{}. |
| 457 |
| 458 \ref{objectIdentity}: Refined definition of \code{identical()}. |
| 459 |
| 460 \ref{propertyExtraction}: Abstract methods are ignored for purposes of property
extraction. |
| 461 |
| 462 \ref{bindingActualsToFormals}: Mismatched arguments lead to \cd{NoSuchMethodErro
r}. |
| 463 |
| 464 \ref{ordinaryInvocation}, \ref{superInvocation}: Correctly account for calls to
\cd{noSuchMethod} due to mismatched arguments. |
| 465 |
| 466 \ref{imports}, \ref{exports}: Provenance of declarations allowed to disambiguat
e imports and exports. |
| 467 |
| 468 \ref{typedef}: Mixin applications are no longer defined via a \TYPEDEF{}. |
| 469 |
| 470 \ref{functionTypes}: All functions must implement \CALL{}. |
| 471 |
| 472 \ref{comments}: Doc comments details are unspecified. |
| 473 |
| 474 \subsubsection{Changes Since Version 0.6} |
| 475 |
| 476 \ref{variables}: Type promotion support added. |
| 477 |
| 478 \ref{formalParameters}: refined scope rules. |
| 479 |
| 480 \ref{classes}: Banned name clashes between type variables and members etc. |
| 481 |
| 482 \ref{factories}: Banned default values in redirecting factories. |
| 483 |
| 484 \ref{constants}: Added constant conditional expressions. |
| 485 |
| 486 \ref{strings}: Allow adjacent single and multiine strings to concatenate. Allow
escaped newlines in multiline strings. |
| 487 |
| 488 \ref{conditional}: Type promotion support added. |
| 489 |
| 490 \ref{logicalBooleanExpressions}: Type promotion support added. |
| 491 |
| 492 \ref{logicalBooleanExpressions} - \ref{bitwiseExpressions}, \ref{operatorPrecede
nce}: Increased precedence of bitwise operations to be higher than equality and
relational expressions. |
| 493 |
| 494 \ref{identifierReference}: Clarified static type rules. Type promotion support a
dded. |
| 495 |
| 496 \ref{typeTest}: Type promotion support added. |
| 497 |
| 498 \ref{if}: Type promotion support added. |
| 499 |
| 500 \ref{return}: Added warning if \RETURN{} without expression mixed with \RETURN{}
with an expression. |
| 501 |
| 502 \ref{typePromotion}: Added notion of type promotion. |
| 503 |
| 504 \ref{typedef}: Banned all recursion in typedefs. |
| 505 |
| 506 |
| 507 \section{Notation} |
| 508 \label{notation} |
| 509 |
| 510 We distinguish between normative and non-normative text. Normative text defines
the rules of Dart. It is given in this font. At this time, non-normative text in
cludes: |
| 511 \begin{itemize} |
| 512 \item[Rationale] Discussion of the motivation for language design decisions appe
ars in italics. \rationale{Distinguishing normative from non-normative helps cla
rify what part of the text is binding and what part is merely expository.} |
| 513 \item[Commentary] Comments such as ``\commentary{The careful reader will have n
oticed that the name Dart has four characters}'' serve to illustrate or clarify
the specification, but are redundant with the normative text. \commentary{The d
ifference between commentary and rationale can be subtle.} \rationale{ Commentar
y is more general than rationale, and may include illustrative examples or clari
fications. } |
| 514 \item[Open questions] (\Q{in this font}). Open questions are points that are uns
ettled in the mind of the author(s) of the specification; expect them (the quest
ions, not the authors; precision is important in a specification) to be eliminat
ed in the final specification. \Q{Should the text at the end of the previous bul
let be rationale or commentary?} |
| 515 \end{itemize} |
| 516 |
| 517 Reserved words and built-in identifiers (\ref{identifierReference}) appear in {
\bf bold}. |
| 518 |
| 519 \commentary{ |
| 520 Examples would be \SWITCH{} or \CLASS{}. |
| 521 } |
| 522 |
| 523 |
| 524 Grammar productions are given in a common variant of EBNF. The left hand side o
f a production ends with a colon. On the right hand side, alternation is repres
ented by vertical bars, and sequencing by spacing. As in PEGs, alternation give
s priority to the left. Optional elements of a production are suffixed by a ques
tion mark like so: \code{anElephant?}. Appending a star to an element of a prod
uction means it may be repeated zero or more times. Appending a plus sign to a
production means it occurs one or more times. Parentheses are used for grouping.
Negation is represented by prefixing an element of a production with a tilde.
Negation is similar to the not combinator of PEGs, but it consumes input if it m
atches. In the context of a lexical production it consumes a single character if
there is one; otherwise, a single token if there is one. |
| 525 |
| 526 \commentary{ An example would be:} |
| 527 |
| 528 \begin{grammar} |
| 529 {\sf |
| 530 {\bf AProduction:}AnAlternative; |
| 531 AnotherAlternative; |
| 532 OneThing After Another; |
| 533 ZeroOrMoreThings*; |
| 534 OneOrMoreThings+; |
| 535 AnOptionalThing?; |
| 536 (Some Grouped Things); |
| 537 \~{}NotAThing; |
| 538 A\_LEXICAL\_THING |
| 539 . |
| 540 } |
| 541 \end{grammar} |
| 542 |
| 543 % need a match anything or a production that does that, so we can correct bugs w
rt use |
| 544 % ~. ~ does not actually parse stuff - it just looks ahead and checks. To get th
e effect of |
| 545 % parsing anything but X, one needs ~X ANYTHING, not just ~X. There are bugs in
the |
| 546 % grammar related to this. |
| 547 % The alternative is to define ~X as anything but X, or to introduce an anthingB
ut(X) |
| 548 % combinator, such as !X |
| 549 |
| 550 Both syntactic and lexical productions are represented this way. Lexical product
ions are distinguished by their names. The names of lexical productions consist
exclusively of upper case characters and underscores. As always, within grammat
ical productions, whitespace and comments between elements of the production are
implicitly ignored unless stated otherwise. |
| 551 Punctuation tokens appear in quotes. |
| 552 |
| 553 Productions are embedded, as much as possible, in the discussion of the construc
ts they represent. |
| 554 |
| 555 A list $x_1, \ldots, x_n$ denotes any list of $n$ elements of the form $x_i, 1 \
le i \le n$. Note that $n$ may be zero, in which case the list is empty. We use
such lists extensively throughout this specification. |
| 556 |
| 557 The notation $[x_1, \ldots, x_n/y_1, \ldots, y_n]E$ denotes a copy of $E$ in whi
ch all occurrences of $y_i, 1 \le i \le n$ have been replaced with $x_i$. |
| 558 |
| 559 We sometimes abuse list or map literal syntax, writing $[o_1, \ldots, o_n]$ (re
spectively $\{k_1: o_1, \ldots, k_n: o_n\}$) where the $o_i$ and $k_i$ may be ob
jects rather than expressions. The intent is to denote a list (respectively map)
object whose elements are the $o_i$ (respectively, whose keys are the $k_i$ and
values are the $o_i$). |
| 560 |
| 561 The specifications of operators often involve statements such as $x$ $op$ $y$ is
equivalent to the method invocation $x.op(y)$. Such specifications should be un
derstood as a shorthand for: |
| 562 \begin{itemize} |
| 563 \item |
| 564 $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$. |
| 565 \end{itemize} |
| 566 |
| 567 \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. |
| 568 } |
| 569 |
| 570 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. |
| 571 |
| 572 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. |
| 573 |
| 574 \commentary{ |
| 575 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. |
| 576 } |
| 577 |
| 578 \section{Overview} |
| 579 \label{overview} |
| 580 |
| 581 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. |
| 582 |
| 583 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. |
| 584 |
| 585 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. |
| 586 |
| 587 \commentary{ |
| 588 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. |
| 589 |
| 590 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. |
| 591 } |
| 592 |
| 593 In checked mode, assignments are dynamically checked, and certain violations of
the type system raise exceptions at run time. |
| 594 |
| 595 \commentary{ |
| 596 The coexistence between optional typing and reification is based on the followin
g: |
| 597 \begin{enumerate} |
| 598 \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. |
| 599 \item Static type annotations determine the types of variables and function decl
arations (including methods and constructors). |
| 600 \item Production mode respects optional typing. Static type annotations do not a
ffect runtime behavior. |
| 601 \item Checked mode utilizes static type annotations and dynamic type information
aggressively yet selectively to provide early error detection during developmen
t. |
| 602 \end{enumerate} |
| 603 } |
| 604 |
| 605 Dart programs are organized in a modular fashion into units called {\em librarie
s} (\ref{librariesAndScripts}). Libraries are units of encapsulation and may be
mutually recursive. |
| 606 |
| 607 \commentary{However they are not first class. To get multiple copies of a libra
ry running simultaneously, one needs to spawn an isolate. |
| 608 } |
| 609 |
| 610 \subsection{Scoping} |
| 611 \label{scoping} |
| 612 |
| 613 A {\em namespace} is a mapping of identifiers to declarations. Let $NS$ be a na
mespace. We say that a name $n$ {\em is in }$NS$ if $n$ is a key of $NS$. We say
a declaration $d$ {\em is in }$NS$ if a key of $NS$ maps to $d$. |
| 614 |
| 615 A scope $S_0$ induces a namespace $NS_0$ that maps the simple name of each varia
ble, type or function declaration $d$ declared in $S_0$ to $d$. Labels are not i
ncluded in the induced namespace of a scope; instead they have their own dedicat
ed namespace. |
| 616 |
| 617 \commentary{It is therefore impossible, e.g., to define a class that declares a
method and a field with the same name in Dart. Similarly one cannot declare a t
op-level function with the same name as a library variable or class. |
| 618 } |
| 619 |
| 620 It is a compile-time error if there is more than one entity with the same name d
eclared in the same scope. |
| 621 |
| 622 \commentary{ |
| 623 In some cases, the name of the declaration differs from the identifier used to d
eclare it. Setters have names that are distinct from the corresponding getters
because they always have an = automatically added at the end, and unary minus ha
s the special name unary-. |
| 624 } |
| 625 |
| 626 Dart is lexically scoped. Scopes may nest. A name or declaration $d$ is {\em
available in scope} $S$ if $d$ is in the namespace induced by $S$ or if $d$ is
available in the lexically enclosing scope of $S$. We say that a name or declar
ation $d$ is {\em in scope} if $d$ is available in the current scope. |
| 627 |
| 628 |
| 629 If a declaration $d$ named $n$ is in the namespace induced by a scope $S$, then
$d$ {\em hides} any declaration named $n$ that is available in the lexically en
closing scope of $S$. |
| 630 |
| 631 Names may be introduced into a scope by declarations within the scope or by ot
her mechanisms such as imports or inheritance. |
| 632 |
| 633 \rationale{ |
| 634 The interaction of lexical scoping and inheritance is a subtle one. Ultimately,
the question is whether lexical scoping takes precedence over inheritance or vi
ce versa. Dart chooses the former. |
| 635 |
| 636 Allowing inherited names to take precedence over locally declared names can crea
te unexpected situations as code evolves. Specifically, the behavior of code in
a subclass can change without warning if a new name is introduced in a supercla
ss. Consider: |
| 637 } |
| 638 |
| 639 \begin{dartCode} |
| 640 \LIBRARY{} L1; |
| 641 \CLASS{} S \{\} |
| 642 |
| 643 \LIBRARY{} L2; |
| 644 \IMPORT{} `L1.dart'; |
| 645 foo() =$>$ 42; |
| 646 \CLASS{} C \EXTENDS{} S\{ bar() =$>$ foo();\} |
| 647 \end{dartCode} |
| 648 |
| 649 \rationale{Now assume a method \code{foo()} is added to \code{S}. } |
| 650 |
| 651 \begin{dartCode} |
| 652 \LIBRARY{} L1; |
| 653 \CLASS{} S \{foo() =$>$ 91;\} |
| 654 \end{dartCode} |
| 655 |
| 656 \rationale{ |
| 657 If inheritance took precedence over the lexical scope, the behavior of \code{C}
would change in an unexpected way. Neither the author of \code{S} nor the author
of \code{C} are necessarily aware of this. In Dart, if there is a lexically vis
ible method \code{foo()}, it will always be called. |
| 658 |
| 659 Now consider the opposite scenario. We start with a version of \code{S} that con
tains \code{foo()}, but do not declare \code{foo()} in library \code{L2}. Again
, there is a change in behavior - but the author of \code{L2} is the one who int
roduced the discrepancy that effects their code, and the new code is lexically v
isible. Both these factors make it more likely that the problem will be detected
. |
| 660 |
| 661 These considerations become even more important if one introduces constructs suc
h as nested classes, which might be considered in future versions of the languag
e. |
| 662 |
| 663 Good tooling should of course endeavor to inform programmers of such situations
(discretely). For example, an identifier that is both inherited and lexically vi
sible could be highlighted (via underlining or colorization). Better yet, tight
integration of source control with language aware tools would detect such change
s when they occur. |
| 664 |
| 665 } |
| 666 |
| 667 |
| 668 |
| 669 |
| 670 \subsection{Privacy} |
| 671 \label{privacy} |
| 672 |
| 673 Dart supports two levels of privacy: {\em public} and {\em private}. A declarati
on is {\em private} iff its name begins with an underscore (the \_ character) ot
herwise it is {\em public.} |
| 674 A declaration $m$ is {\em accessible to library $L$} if $m$ is declared in $L$
or if $m$ is public. |
| 675 |
| 676 \commentary{ |
| 677 This means private declarations may only be accessed within the library in which
they are declared. |
| 678 } |
| 679 |
| 680 Privacy applies only to declarations within a library, not to library declaratio
ns themselves. |
| 681 |
| 682 \rationale{ |
| 683 Libraries do not reference each other by name and so the idea of a private libra
ry is meaningless. |
| 684 Thus, if the name of a library begins with an underscore, it has no special sign
ificance. |
| 685 } |
| 686 |
| 687 \rationale{Privacy is, at this point, a static notion tied to a particular piece
of code (a library). It is designed to support software engineering concerns ra
ther than security concerns. Untrusted code should always run in an another isol
ate. It is possible that libraries will become first class objects and privacy
will be a dynamic notion tied to a library instance. |
| 688 |
| 689 Privacy is indicated by the name of a declaration - hence privacy and naming are
not orthogonal. This has the advantage that both humans and machines can recogn
ize access to private declarations at the point of use without knowledge of the
context from which the declaration is derived.} |
| 690 |
| 691 \subsection{Concurrency} |
| 692 |
| 693 Dart code is always single threaded. There is no shared-state concurrency in Dar
t. Concurrency is supported via actor-like entities called {\em isolates}. |
| 694 |
| 695 An isolate is a unit of concurrency. It has its own memory and its own thread of
control. Isolates communicate by message passing (\ref{sendingMessages}). No st
ate is ever shared between isolates. Isolates are created by spawning (\ref{spaw
ningAnIsolate}). |
| 696 |
| 697 |
| 698 \section{Errors and Warnings} |
| 699 \label{errorsAndWarnings} |
| 700 |
| 701 This specification distinguishes between several kinds of errors. |
| 702 |
| 703 {\em Compile-time errors} are errors that preclude execution. A compile-time err
or must be reported by a Dart compiler before the erroneous code is executed. |
| 704 |
| 705 \rationale{A Dart implementation has considerable freedom as to when compilation
takes place. Modern programming language implementations often interleave compi
lation and execution, so that compilation of a method may be delayed, e.g., unt
il it is first invoked. Consequently, compile-time errors in a method $m$ may be
reported as late as the time of $m$'s first invocation. |
| 706 |
| 707 As a web language, Dart is often loaded directly from source, with no intermedia
te binary representation. In the interests of rapid loading, Dart implementation
s may choose to avoid full parsing of method bodies, for example. This can be do
ne by tokenizing the input and checking for balanced curly braces on method body
entry. In such an implementation, even syntax errors will be detected only when
the method needs to be executed, at which time it will be compiled (JITed). |
| 708 |
| 709 In a development environment a compiler should of course report compilation erro
rs eagerly so as to best serve the programmer. |
| 710 } |
| 711 |
| 712 If an uncaught compile-time error occurs within the code of a running isolate $A
$, $A$ is immediately suspended. The only circumstance where a compile-time err
or could be caught would be via code run reflectively, where the mirror system c
an catch it. |
| 713 |
| 714 \rationale{Typically, once a compile-time error is thrown and $A$ is suspended,
$A$ will then be terminated. However, this depends on the overall environment. |
| 715 A Dart engine runs in the context of an {\em embedder}, |
| 716 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. |
| 717 } |
| 718 |
| 719 {\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. |
| 720 |
| 721 {\em Dynamic type errors} are type errors reported in checked mode. |
| 722 |
| 723 {\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. |
| 724 |
| 725 If an uncaught exception is thrown by a running isolate $A$, $A$ is immediately
suspended. |
| 726 |
| 727 |
| 728 \section{Variables} |
| 729 \label{variables} |
| 730 |
| 731 Variables are storage locations in memory. |
| 732 |
| 733 \begin{grammar} |
| 734 {\bf variableDeclaration:} |
| 735 declaredIdentifier (`,' identifier)* |
| 736 . |
| 737 |
| 738 {\bf declaredIdentifier:} |
| 739 metadata finalConstVarOrType identifier |
| 740 . |
| 741 |
| 742 {\bf finalConstVarOrType:}\FINAL{} type?; |
| 743 \CONST{} type?; |
| 744 varOrType |
| 745 . |
| 746 |
| 747 {\bf varOrType:}\VAR{}; |
| 748 type |
| 749 . |
| 750 |
| 751 {\bf initializedVariableDeclaration:} |
| 752 declaredIdentifier (`=' expression)? (`,' initializedIdentifier)* % could
do top level here |
| 753 . |
| 754 |
| 755 {\bf initializedIdentifier:} |
| 756 identifier (`=' expression)? % could do top-level here |
| 757 . |
| 758 |
| 759 {\bf initializedIdentifierList:} |
| 760 initializedIdentifier (`,' initializedIdentifier)* |
| 761 . |
| 762 |
| 763 |
| 764 |
| 765 |
| 766 \end{grammar} |
| 767 |
| 768 A variable that has not been initialized has the initial value \NULL{} (\ref{nul
l}). |
| 769 |
| 770 A variable declared at the top-level of a library is referred to as either a {\e
m library variable} or simply a top-level variable. |
| 771 |
| 772 A {\em static variable} is a variable that is not associated with a particular i
nstance, but rather with an entire library or class. Static variables include l
ibrary variables and class variables. Class variables are variables whose declar
ation is immediately nested inside a class declaration and includes the modifier
\STATIC{}. A library variable is implicitly static. It is a compile-time error
to preface a top-level variable declaration with the built-in identifier (\ref{
identifierReference}) \STATIC{}. |
| 773 |
| 774 Static variable declarations are initialized lazily. When a static variable $v$
is read, iff it has not yet been assigned, it is set to the result of evaluatin
g its initializer. The precise rules are given in section \ref{evaluationOfImpli
citVariableGetters}. |
| 775 |
| 776 \rationale{The lazy semantics are given because we do not want a language where
one tends to define expensive initialization computations, causing long applicat
ion startup times. This is especially crucial for Dart, which must support the c
oding of client applications. |
| 777 } |
| 778 |
| 779 A {\em final variable} is a variable whose binding is fixed upon initialization;
a final variable $v$ will always refer to the same object after $v$ has been in
itialized. The declaration of a final variable must include the modifier \FINAL
{}. |
| 780 |
| 781 It is a static warning if a final instance variable that has been initialized at
its point of declaration is also initialized in a constructor. |
| 782 % It is a static warning if a final instance variable that has been initialized
by means of an initializing formal of a constructor is also initialized elsewhe
re in the same constructor. |
| 783 It is a compile-time error if a local variable $v$ is final and $v$ is not initi
alized at its point of declaration. |
| 784 |
| 785 \commentary{ |
| 786 |
| 787 A library or static variable is guaranteed to have an initializer at its declara
tion by the grammar. |
| 788 |
| 789 Attempting to assign to a final variable anywhere except in its declaration or i
n a constructor header will cause a runtime error to be thrown as discussed bel
ow. The assignment will also give rise to a static warning. Any repeated assignm
ent to a final variable will also lead to a runtime error. |
| 790 |
| 791 Taken as a whole, the rules ensure that any attempt to execute multiple assignme
nts to a final variable will yield static warnings and repeated assignments will
fail dynamically. |
| 792 } |
| 793 |
| 794 A {\em constant variable} is a variable whose declaration includes the modifier
\CONST{}. A constant variable is always implicitly final. A constant variable mu
st be initialized to a compile-time constant (\ref{constants}) or a compile-time
error occurs. |
| 795 |
| 796 We say that a variable $v$ is {\em potentially mutated} in some scope $s$ if $v$
is not final or constant and an assignment to $v$ occurs in $s$. |
| 797 |
| 798 If a variable declaration does not explicitly specify a type, the type of the de
clared variable(s) is \DYNAMIC{}, the unknown type (\ref{typeDynamic}). |
| 799 |
| 800 Static and instance variable declarations always induce implicit getters and set
ters. |
| 801 The scope into which the implicit getters and setters are introduced depends on
the kind of variable declaration involved. |
| 802 |
| 803 A library variable introduces a getter and a setter into the top level scope of
the enclosing library. A static class variable introduces a static getter and a
static setter into the immediately enclosing class. An instance variable introdu
ces an instance getter and an instance setter into the immediately enclosing cla
ss. |
| 804 |
| 805 Local variables are added to the innermost enclosing scope. They do not induce
getters and setters. A local variable may only be referenced at a source code l
ocation that is after its initializer, if any, is complete, or a a compile-time
error occurs. |
| 806 |
| 807 \commentary{ |
| 808 The example below illustrates the expected behavior. A variable $x$ is declared
at the library level, and another $x$ is declared inside the function $f$. |
| 809 } |
| 810 |
| 811 \begin{dartCode} |
| 812 \VAR{} x = 0; |
| 813 |
| 814 f(y) \{ |
| 815 \VAR{} z = x; // compile-time error |
| 816 if (y) \{ |
| 817 x = x + 1; // two compile time errors |
| 818 print(x); // compile time error |
| 819 \} |
| 820 \VAR{} x = x++; // compile time error |
| 821 print(x); |
| 822 \} |
| 823 \end{dartCode} |
| 824 |
| 825 \commentary{ |
| 826 The declaration inside $f$ hides the enclosing one. So all references to $x$ in
side $f$ refer to the inner declaration of $x$. However, many of these reference
s are illegal, because they appear before the declaration. The assignment to $z$
is one such case. The assignment to $x$ in the \IF{} statement suffers from mul
tiple problems. The right hand side reads $x$ before its declaration, and the le
ft hand side assigns to $x$ before its declaration. Each of these are, independe
ntly, compile time errors. The print statement inside the \IF{} is also illegal
. |
| 827 |
| 828 The inner declaration of $x$ is itself erroneous because its right hand side att
empts to read $x$ before the declaration has terminated. The left hand side is
not, technically, a reference or an assignment but a declaration and so is legal
. The last print statement is perfectly legal as well. |
| 829 } |
| 830 |
| 831 \commentary { |
| 832 As another example \code{var x = 3, y = x;} is legal, because \code{x} is refer
enced after its initializer. |
| 833 |
| 834 } |
| 835 |
| 836 % the grammar does not support local getters and setters. The local var discussi
on does not seem to mention getters and setters based semantics. It simply discu
sses the creation of the variable, not its access. Access is either assignment o
r identifiers. Identifiers ignore the getter story. |
| 837 |
| 838 The following rules apply to all static and instance variables. |
| 839 |
| 840 A variable declaration of one of the forms \code{$T$ $v$;}, \code{$T$ $v$ = $
e$;} , \code{\CONST{} $T$ $v$ = $e$;}, \code{\FINAL{} $T$ $v$;} or \code{\FINA
L{} $T$ $v$ = $e$;} always induces an implicit getter function (\ref{getters})
with signature |
| 841 |
| 842 $T$ \GET{} $v$ |
| 843 |
| 844 whose invocation evaluates as described below (\ref{evaluationOfImplicitVariable
Getters}). |
| 845 |
| 846 |
| 847 A variable declaration of one of the forms \code{\VAR{} $v$;}, \code{\VAR{} $
v$ = $e$;} , \code{\CONST{} $v$ = $e$;}, \code{\FINAL{} $v$;} or \code{\FINAL{}
$v$ = $e$;} always induces an implicit getter function with signature |
| 848 |
| 849 \GET{} $v$ |
| 850 |
| 851 whose invocation evaluates as described below (\ref{evaluationOfImplicitVariabl
eGetters}). |
| 852 |
| 853 A non-final variable declaration of the form \code{{} $T$ $v$;} or the form \
code{$T$ $v$ = $e$;} always induces an implicit setter function (\ref{setters
}) with signature |
| 854 |
| 855 \VOID{} \SET{} $v=(T$ $x)$ |
| 856 |
| 857 whose execution sets the value of $v$ to the incoming argument $x$. |
| 858 |
| 859 A non-final variable declaration of the form \code{\VAR{} $v$;} or the form \
code{\VAR{} $v$ = $e$;} always induces an implicit setter function with signa
ture |
| 860 |
| 861 \SET{} $v=(x)$ |
| 862 |
| 863 whose execution sets the value of $v$ to the incoming argument $x$. |
| 864 |
| 865 % A final variable introduces a setter that throws and causes a type warning |
| 866 |
| 867 A final or constant variable declaration of the form \code{\FINAL{} $T$ $v$;},
\code{\FINAL{} $T$ $v$ = $e$;} or the form \code{\CONST{} $T$ $v$ = $e$;} alw
ays induces an implicit setter function (\ref{setters}) with signature |
| 868 |
| 869 \VOID{} \SET{} $v=(T$ $x)$ |
| 870 |
| 871 whose execution causes a runtime exception. It is a static warning to invoke suc
h a setter. |
| 872 |
| 873 A final variable declaration of the form \code{\FINAL{} $v$;}, \code{\FINAL{}
$v$ = $e$;} or the form \code{\CONST{} $v$ = $e$;} always induces an implici
t setter function with signature |
| 874 |
| 875 \SET{} $v=(x)$ |
| 876 |
| 877 whose execution causes a runtime exception. It is a static warning to invoke suc
h a setter. % maybe redundant with rules for assignment? |
| 878 |
| 879 \rationale{ |
| 880 Creating a setter that may not be used may seem pointless, but it prevents situa
tions where a setter from an enclosing scope might be accidentally accessed from
a scope that defines an immutable variable. |
| 881 } |
| 882 |
| 883 |
| 884 \subsection{Evaluation of Implicit Variable Getters} |
| 885 \label{evaluationOfImplicitVariableGetters} |
| 886 |
| 887 Let $d$ be the declaration of a static or instance variable $v$. If $d$ is an i
nstance variable, then the invocation of the implicit getter of $v$ evaluates t
o the value stored in $v$. |
| 888 If $d$ is a static or library variable then the implicit getter method of $v$ ex
ecutes as follows: |
| 889 \begin{itemize} |
| 890 \item {\bf Non-constant variable declaration with initializer}. If $d$ is of one
of the forms \code{\VAR{} $v$ = $e$;} , \code{$T$ $v$ = $e$;} , \code{\FINAL
{} $v$ = $e$;} , \code{\FINAL{} $T$ $v$ = $e$;}, \code{\STATIC{} $v$ = $e$; },
\code{\STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code
{\STATIC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ th
en the initializer expression $e$ is evaluated. If, during the evaluation of $e$
, the getter for $v$ is invoked, a \code{CyclicInitializationError} is thrown. I
f the evaluation succeeded yielding an object $o$, let $r = o$, otherwise let $r
= \NULL{}$. In any case, $r$ is stored into $v$. The result of executing the ge
tter is $r$. |
| 891 \item {\bf Constant variable declaration}. If $d$ is of one of the forms \code{
\CONST{} $v$ = $e$; } , \code{\CONST{} $T$ $v$ = $e$; }, \code{\STATIC{} \CON
ST{} $v$ = $e$; } or \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the
getter is the value of the compile time constant $e$. \commentary{Note that a c
ompile time constant cannot depend on itself, so no cyclic references can occur.
} |
| 892 Otherwise |
| 893 \item {\bf Variable declaration without initializer}. The result of executing th
e getter method is the value stored in $v$. |
| 894 \end{itemize} |
| 895 |
| 896 |
| 897 |
| 898 |
| 899 |
| 900 \section{Functions} |
| 901 \label{functions} |
| 902 |
| 903 Functions abstract over executable actions. |
| 904 |
| 905 \begin{grammar} |
| 906 {\bf functionSignature:} |
| 907 metadata returnType? identifier formalParameterList |
| 908 . |
| 909 |
| 910 {\bf returnType:} |
| 911 \VOID{}; |
| 912 type |
| 913 . |
| 914 |
| 915 {\bf functionBody:}`={\escapegrammar \gt}' expression `{\escapegrammar ;}'; |
| 916 block |
| 917 . |
| 918 |
| 919 {\bf block:} |
| 920 `\{' statements `\}' |
| 921 . |
| 922 |
| 923 \end{grammar} |
| 924 |
| 925 Functions include function declarations (\ref{functionDeclarations}), methods (
\ref{instanceMethods}, \ref{staticMethods}), getters (\ref{getters}), setters
(\ref{setters}), constructors (\ref{constructors}) and function literals (\re
f{functionExpressions}). |
| 926 |
| 927 All functions have a signature and a body. The signature describes the formal pa
rameters of the function, and possibly its name and return type. A function bod
y is either: |
| 928 \begin{itemize} |
| 929 \item A block statement (\ref{blocks}) containing the statements (\ref{stateme
nts}) executed by the function. In this case, if the last statement of a functio
n is not a return statement, the statement \code{\RETURN{};} is implicitly appen
ded to the function body. |
| 930 |
| 931 \rationale{ |
| 932 Because Dart is optionally typed, we cannot guarantee that a function that does
not return a value will not be used in the context of an expression. Therefore,
every function must return a value. A \RETURN{} without an expression returns \N
ULL{}. See further discussion in section \ref{return}. |
| 933 } |
| 934 |
| 935 OR |
| 936 \item of the form \code{=$>$ $e$} which is equivalent to a body of the form \c
ode{\{\RETURN{} $e$;\}}. |
| 937 \end{itemize} |
| 938 |
| 939 |
| 940 |
| 941 % A function has a formal parameter scope and a body scope. The enclosing scope
of a function's body scope is its formal parameter scope. The enclosing scope o
f the formal parameter scope of a function is the enclosing scope of the functi
on. |
| 942 |
| 943 % The body of a function $f$ is processed within the body scope of $f$. |
| 944 %\rationale{This may seem obvious, but needs to be stated.} |
| 945 % \commentary{It follows from the above rules that the formal parameters of a fu
nction may be referenced within its body. } |
| 946 |
| 947 \subsection{Function Declarations} |
| 948 \label{functionDeclarations} |
| 949 |
| 950 A {\em function declaration} is a function that is neither a member of a class n
or a function literal. Function declarations include {\em library functions}, wh
ich are function declarations |
| 951 %(including getters and setters) |
| 952 at the top level of a library, and {\em local functions}, which are function dec
larations declared inside other functions. Library functions are often referred
to simply as top-level functions. |
| 953 |
| 954 A function declaration consists of an identifier indicating the function's name,
possibly prefaced by a return type. The function name is followed by a signatur
e and body. For getters, the signature is empty. The body is empty for function
s that are external. |
| 955 |
| 956 The scope of a library function is the scope of the enclosing library. The scope
of a local function is described in section \ref{localFunctionDeclaration}. In
both cases, the name of the function is in scope in its formal parameter scope
(\ref{formalParameters}). |
| 957 |
| 958 %A function declaration of the form $T_0$ $id(T_1$ $a_1, \ldots, T_n$ $a_n, [T_
{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$ is equivalent to
a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ldots
, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k}= d_k])\{s\}$},
where $F$ is the function type alias (\ref{typedef}) \code{\TYPEDEF{} $T_0$ $F(T
_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}])$}.
Likewise, a function declaration of the form $id(T_1$ $a_1, \ldots, T_n$ $a_n
, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s\}$ is equivalen
t to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \
ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{s
\}$}, where $F$ is the function type alias \code{\TYPEDEF{} $F(T_1$ $a_1, \ldot
s, T_n$ $a_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}])$}. |
| 959 |
| 960 %\Q{We need to cover library getters as well.} |
| 961 |
| 962 %\Q{ The definition in terms of variables is untrue, because the code would be i
llegal. The initializer cannot refer to the function name in this case. I belie
ve the best fix is to relax this |
| 963 %requirement in the case of closures. See bug 315. |
| 964 %} |
| 965 |
| 966 %\commentary{ |
| 967 %Some obvious conclusions: |
| 968 |
| 969 %A function declaration of the form $id(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$
$x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k]) => e$ is equivalent to a varia
ble declaration of the form \code{\FINAL{} $id$ = ($(T_1$ $a_1, \ldots, T_n$ $a
_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k])=> e$}. |
| 970 |
| 971 %A function literal of the form $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+
1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k]) => e$ is equivalent to a function li
teral of the form \code{$(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_
1, \ldots, T_{n+k}$ $x_{n+k} = d_k])\{$ \RETURN{} $e$;\}}. |
| 972 %} |
| 973 |
| 974 %A function declaration of the form $T_0$ $id(T_1$ $a_1, \ldots, T_n$ $a_n, \{T
_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})\{s\}$ is equivalent t
o a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1$ $a_1, \ldo
ts, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})\{s\
}$}, where $F$ is the function type alias (\ref{typedef}) \code{\TYPEDEF{} $T_0$
$F(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}
]\}$}. Likewise, a function declaration of the form $id(T_1$ $a_1, \ldots, T_
n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})\{s\}$ is
equivalent to a variable declaration of the form \code{\FINAL{} $F$ $id$ = $(T_1
$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k}
: d_k\})\{s\}$}, where $F$ is the function type alias \code{\TYPEDEF{} $F(T_1$
$a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\})$}. |
| 975 |
| 976 It is a compile-time error to preface a function declaration with the built-in i
dentifier \STATIC{}. |
| 977 |
| 978 \subsection{Formal Parameters} |
| 979 \label{formalParameters} |
| 980 |
| 981 Every function includes a {\em formal parameter list}, which consists of a list
of required positional parameters (\ref{requiredFormals}), followed by any optio
nal parameters (\ref{optionalFormals}). The optional parameters may be specified
either as a set of named parameters or as a list of positional parameters, but
not both. |
| 982 |
| 983 The formal parameter list of a function introduces a new scope known as the func
tion`s {\em formal parameter scope}. The formal parameter scope of a function $f
$ is enclosed in the scope where $f$ is declared. Every formal parameter intr
oduces a local variable into the formal parameter scope. However, the scope of a
function's signature is the function's enclosing scope, not the formal paramete
r scope. |
| 984 |
| 985 The body of a function introduces a new scope known as the function`s {\em body
scope}. The body scope of a function $f$ is enclosed in the scope introduced
by the formal parameter scope of $f$. |
| 986 |
| 987 |
| 988 %The formal parameter scope of a function maps the name of each formal parameter
$p$ to the value $p$ is bound to. |
| 989 |
| 990 % The formal parameters of a function are processed in the enclosing scope of th
e function. |
| 991 % \commentary{this means that the parameters themselves may not be referenced wi
thin the formal parameter list.} |
| 992 |
| 993 It is a compile-time error if a formal parameter is declared as a constant varia
ble (\ref{variables}). |
| 994 |
| 995 \begin{grammar} |
| 996 {\bf formalParameterList:}`(' `)'; |
| 997 `(' normalFormalParameters ( `,' optionalFormalParameters)? `)'; |
| 998 `(' optionalFormalParameters `)' |
| 999 . |
| 1000 %\end{grammar} |
| 1001 %} |
| 1002 |
| 1003 %\begin{grammar} |
| 1004 %formalParameterList: |
| 1005 % '(' restFormalParameter? ')'; |
| 1006 % '(' namedFormalParameters ')'; |
| 1007 % '(' normalFormalParameters normalFormalParameterTail? ')' |
| 1008 % . |
| 1009 |
| 1010 {\bf normalFormalParameters:} |
| 1011 normalFormalParameter (`,' normalFormalParameter)* |
| 1012 . |
| 1013 |
| 1014 {\bf optionalFormalParameters:}optionalPositionalFormalParameters; |
| 1015 namedFormalParameters |
| 1016 . |
| 1017 |
| 1018 {\bf optionalPositionalFormalParameters:} |
| 1019 `[' defaultFormalParameter (`,' defaultFormalParameter)* `]' |
| 1020 . |
| 1021 {\bf namedFormalParameters:} |
| 1022 `\{' defaultNamedParameter (`,' defaultNamedParameter)* `\}' |
| 1023 . |
| 1024 \end{grammar} |
| 1025 |
| 1026 %Formal parameters are always \FINAL{}. |
| 1027 %\Q{We're awaiting some data on whether enforcing this would cause widespread pa
in.} |
| 1028 %A formal parameter is always considered to be initialized. \rationale{This is
because it will always be initialized by the call - even if it is optional.} |
| 1029 |
| 1030 |
| 1031 \subsubsection{Required Formals} |
| 1032 \label{requiredFormals} |
| 1033 |
| 1034 A {\em required formal parameter} may be specified in one of three ways: |
| 1035 \begin{itemize} |
| 1036 \item By means of a function signature that names the parameter and describes it
s type as a function type (\ref{functionTypes}). It is a compile-time error if
any default values are specified in the signature of such a function type.% expl
ain what the type is in this case? Where is this described in general? |
| 1037 \item As an initializing formal, which is only valid as a parameter to a generat
ive constructor (\ref{generativeConstructors}). % do we need to say this, or any
thing more? |
| 1038 \item Via an ordinary variable declaration (\ref{variables}). |
| 1039 \end{itemize} |
| 1040 |
| 1041 \begin{grammar} |
| 1042 {\bf normalFormalParameter:}functionSignature; |
| 1043 fieldFormalParameter; |
| 1044 simpleFormalParameter |
| 1045 . |
| 1046 |
| 1047 {\bf simpleFormalParameter:}declaredIdentifier; |
| 1048 metadata identifier |
| 1049 . |
| 1050 |
| 1051 {\bf fieldFormalParameter:} |
| 1052 metadata finalConstVarOrType? \THIS{} `{\escapegrammar .}' identifier formalP
arameterList? |
| 1053 . |
| 1054 \end{grammar} |
| 1055 |
| 1056 %\subsubsection{Rest Formals} |
| 1057 |
| 1058 %A rest formal $R$ must be the last parameter in a formal parameter list. If a
type $T$ is specified for $R$, it signifies that the type of $R$ is $T[]$. |
| 1059 |
| 1060 %\begin{grammar} |
| 1061 %restFormalParameter: |
| 1062 % finalConstVarOrType? '{\escapegrammar ...}' identifier |
| 1063 %\end{grammar} |
| 1064 |
| 1065 \subsubsection{Optional Formals} |
| 1066 \label{optionalFormals} |
| 1067 |
| 1068 Optional parameters may be specified and provided with default values. |
| 1069 |
| 1070 \begin{grammar} |
| 1071 {\bf defaultFormalParameter:} |
| 1072 normalFormalParameter ('=' expression)? |
| 1073 . |
| 1074 |
| 1075 {\bf defaultNamedParameter:} |
| 1076 normalFormalParameter ( `{\escapegrammar :}' expression)? |
| 1077 . |
| 1078 \end{grammar} |
| 1079 |
| 1080 It is a compile-time error if the default value of an optional parameter is not
a compile-time constant (\ref{constants}). If no default is explicitly specified
for an optional parameter an implicit default of \NULL{} is provided. |
| 1081 |
| 1082 It is a compile-time error if the name of a named optional parameter begins with
an `\_' character. |
| 1083 |
| 1084 \rationale{ |
| 1085 The need for this restriction is a direct consequence of the fact that naming a
nd privacy are not orthogonal. |
| 1086 If we allowed named parameters to begin with an underscore, they would be consid
ered private and inaccessible to callers from outside the library where it was d
efined. If a method outside the library overrode a method with a private optiona
l name, it would not be a subtype of the original method. The static checker wou
ld of course flag such situations, but the consequence would be that adding a pr
ivate named formal would break clients outside the library in a way they could n
ot easily correct. |
| 1087 } |
| 1088 |
| 1089 \subsection{Type of a Function} |
| 1090 \label{typeOfAFunction} |
| 1091 |
| 1092 If a function does not declare a return type explicitly, its return type is \DYN
AMIC{} (\ref{typeDynamic}). |
| 1093 |
| 1094 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p
_n$, return type $T_0$ and no optional parameters. Then the type of $F$ is $(T_1
,\ldots, T_n) \rightarrow T_0$. |
| 1095 |
| 1096 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p
_n$, return type $T_0$ and positional optional parameters $T_{n+1}$ $p_{n+1}, \l
dots, T_{n+k}$ $ p_{n+k}$. Then the type of $F$ is $(T_1 ,\ldots, T_n, [T_{n+1}$
$p_{n+1}, \ldots, T_{n+k}$ $p_{n+k}]) \rightarrow T_0$. |
| 1097 |
| 1098 Let $F$ be a function with required formal parameters $T_1$ $p_1 \ldots, T_n$ $p
_n$, return type $T_0$ and named optional parameters $T_{n+1}$ $p_{n+1}, \ldots,
T_{n+k}$ $ p_{n+k}$. Then the type of $F$ is $(T_1 ,\ldots, T_n, \{T_{n+1}$ $p_
{n+1}, \ldots, T_{n+k}$ $p_{n+k}\}) \rightarrow T_0$. |
| 1099 |
| 1100 The run time type of a function object always implements the class \cd{Function}
. |
| 1101 |
| 1102 \commentary{ |
| 1103 One cannot assume, based on the above, that given a function \cd{f}, \cd{f.runt
imeType} will actually be \cd{Function}, or that any two distinct function objec
ts necessarily have the same runtime type. |
| 1104 } |
| 1105 |
| 1106 \rationale{ |
| 1107 It is up to the implementation to choose an appropriate representation for funct
ions. |
| 1108 For example, consider that a closure produced via property extraction treats equ
ality different from ordinary closures, and is therefore likely a different clas
s. Implementations may also use different classes for functions based on arity a
nd or type. Arity may be implicitly affected by whether a function is an instanc
e method (with an implicit receiver parameter) or not. The variations are manifo
ld, and so this specification only guarantees that function objects are instance
s of some class that is considered to implement \cd{Function}. |
| 1109 |
| 1110 } |
| 1111 |
| 1112 \subsection{External Functions} |
| 1113 \label{externalFunctions} |
| 1114 |
| 1115 An {\em external function} is a function whose body is provided separately from
its declaration. An external function may be a top-level function (\ref{librarie
sAndScripts}), a method (\ref{instanceMethods}, \ref{staticMethods}), a getter (
\ref{getters}), a setter (\ref{setters}) or a non-redirecting constructor (\ref{
generativeConstructors}, \ref{factories}). External functions are introduced via
the built-in identifier \EXTERNAL{} (\ref{identifierReference}) followed by th
e function signature. |
| 1116 |
| 1117 \rationale{ |
| 1118 External functions allow us to introduce type information for code that is not
statically known to the Dart compiler. |
| 1119 } |
| 1120 |
| 1121 \commentary{ |
| 1122 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. |
| 1123 } |
| 1124 |
| 1125 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. |
| 1126 |
| 1127 The actual syntax is given in sections \ref{classes} and \ref{librariesAndScript
s} below. |
| 1128 |
| 1129 \section{Classes} |
| 1130 \label{classes} |
| 1131 |
| 1132 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}). |
| 1133 |
| 1134 \begin{grammar} |
| 1135 {\bf classDefinition:} |
| 1136 metadata \ABSTRACT{}? \CLASS{} identifier typeParameters? (superclass mixins?)?
interfaces? \\ |
| 1137 `\{' (metadata classMemberDefinition)* `\}'; |
| 1138 |
| 1139 metadata \ABSTRACT{}? \CLASS{} mixinApplicationClass |
| 1140 . |
| 1141 |
| 1142 {\bf mixins:} |
| 1143 \WITH{} typeList |
| 1144 . |
| 1145 |
| 1146 {\bf classMemberDefinition:}declaration `{\escapegrammar ;}' ; |
| 1147 methodSignature functionBody |
| 1148 . |
| 1149 |
| 1150 {\bf methodSignature:}constructorSignature initializers?; |
| 1151 factoryConstructorSignature; |
| 1152 \STATIC{}? functionSignature; |
| 1153 \STATIC{}? getterSignature; |
| 1154 \STATIC{}? setterSignature; |
| 1155 operatorSignature |
| 1156 . |
| 1157 |
| 1158 {\bf declaration:}constantConstructorSignature (redirection $|$ initializers)?; |
| 1159 constructorSignature (redirection $|$ initializers)?; |
| 1160 \EXTERNAL{} constantConstructorSignature; |
| 1161 \EXTERNAL{} constructorSignature; |
| 1162 ((\EXTERNAL{} \STATIC{} ?))? getterSignature; |
| 1163 ((\EXTERNAL{} \STATIC{}?))? setterSignature; |
| 1164 \EXTERNAL{}? operatorSignature; |
| 1165 ((\EXTERNAL{} \STATIC{}?))? functionSignature; |
| 1166 \STATIC{} (\FINAL{} $|$ \CONST{}) type? staticFinalDeclarationList; |
| 1167 \CONST{} type? staticFinalDeclarationList; |
| 1168 \FINAL{} type? initializedIdentifierList; |
| 1169 \STATIC{}? (\VAR{} $|$ type) initializedIdentifierList |
| 1170 . |
| 1171 |
| 1172 {\bf staticFinalDeclarationList:} |
| 1173 staticFinalDeclaration (`,' staticFinalDeclaration)* |
| 1174 . |
| 1175 |
| 1176 {\bf staticFinalDeclaration:} |
| 1177 identifier `=' expression |
| 1178 . |
| 1179 |
| 1180 \end{grammar} |
| 1181 |
| 1182 A class has constructors, instance members and static members. The instance mem
bers of a class are its instance methods, getters, setters and instance variable
s. The static members of a class are its static methods, getters, setters and st
atic variables. The members of a class are its static and instance members. |
| 1183 |
| 1184 % A class has a static scope and an instance scope. The enclosing scope of the s
tatic scope of a non-generic class is the enclosing scope of the class declarati
on. The enclosing scope of the static scope of a generic class is the type param
eter scope (\ref{}) of the generic class declaration. |
| 1185 %The enclosing scope of a class' instance scope is the class' static scope. |
| 1186 |
| 1187 %The enclosing scope of an instance member declaration is the instance scope of
the class in which it is declared. |
| 1188 |
| 1189 %The enclosing scope of a static member declaration is the static scope of the c
lass in which it is declared. |
| 1190 |
| 1191 |
| 1192 Every class has a single superclass except class \code{Object} which has no sup
erclass. A class may implement a number of interfaces |
| 1193 %, either |
| 1194 by declaring them in its implements clause (\ref{superinterfaces}). |
| 1195 % or via interface injection declarations (\ref{interfaceInjection}) outside the
class declaration |
| 1196 |
| 1197 |
| 1198 An {\em abstract class} is |
| 1199 %either |
| 1200 a class that is explicitly declared with the \ABSTRACT{} modifier, either by m
eans of a class declaration or via a type alias (\ref{typedef}) for a mixin appl
ication (\ref{mixinApplication}). A {\em concrete class} is a class that is not
abstract. |
| 1201 %, or a class that declares at least one abstract method (\ref{abstractInstance
Members}). |
| 1202 |
| 1203 \rationale{ |
| 1204 %The abstract modifier for classes is intended to be used in scenarios where an
abstract class $A$ inherits from another abstract class $B$. In such a situation
, it may be that A$ $itself does not declare any abstract methods. In the absenc
e of an abstract modifier on the class, the class would be interpreted as a conc
rete class. However, w |
| 1205 We want different behavior for concrete classes and abstract classes. If $A$ is
intended to be abstract, we want the static checker to warn about any attempt to
instantiate $A$, and we do not want the checker to complain about unimplemented
methods in $A$. In contrast, if $A$ is intended to be concrete, the checker sho
uld warn about all unimplemented methods, but allow clients to instantiate it fr
eely. |
| 1206 } |
| 1207 |
| 1208 The {\em interface of class $C$} is an implicit interface that declares instance
members that correspond to the instance members declared by $C$, and whose dire
ct superinterfaces are the direct superinterfaces of $C$ (\ref{superinterfaces})
. When a class name appears as a type, that name denotes the interface of the cl
ass. |
| 1209 |
| 1210 It is a compile-time error if a class declares two members of the same name. |
| 1211 %, except that a getter and a setter may be declared with the same name provide
d both are instance members or both are static members. |
| 1212 It is a compile-time error if a class has an instance member and a static member
with the same name. |
| 1213 % It is a compile-time error if a generic (\ref{generics}) class declares a memb
er with the same name as one of its type parameters. |
| 1214 |
| 1215 \commentary{Here are simple examples, that illustrate the difference between ``h
as a member'' and ``declares a member''. For example, \code{B} {\em declares} on
e member named \code{f}, but {\em has} two such members. The rules of inheritanc
e determine what members a class has. |
| 1216 } |
| 1217 |
| 1218 \begin{dartCode} |
| 1219 \CLASS{} A \{ |
| 1220 \VAR{} i = 0; |
| 1221 \VAR{} j; |
| 1222 f(x) =$>$ 3; |
| 1223 \} |
| 1224 |
| 1225 \CLASS{} B \EXTENDS{} A \{ |
| 1226 int i = 1; // getter i and setter i= override versions from A |
| 1227 \STATIC{} j; // compile-time error: static getter \& setter conflict with |
| 1228 //instance getter \& setter |
| 1229 |
| 1230 /* compile-time error: static method conflicts with instance method */ |
| 1231 \STATIC{} f(x) =$>$ 3; |
| 1232 \} |
| 1233 \end{dartCode} |
| 1234 |
| 1235 It is a compile time error if a class $C$ declares a member with the same name a
s $C$. It is a compile time error if a generic class declares a type variable wi
th the same name as the class or any of its members or constructors. |
| 1236 |
| 1237 \subsection{Instance Methods} |
| 1238 \label{instanceMethods} |
| 1239 |
| 1240 Instance methods are functions (\ref{functions}) whose declarations are immediat
ely contained within a class declaration and that are not declared \STATIC{}. Th
e instance methods of a class $C$ are those instance methods declared by $C$ and
the instance methods inherited by $C$ from its superclass. |
| 1241 |
| 1242 %make these warnings if possible |
| 1243 |
| 1244 It is a static warning if an instance method $m_1$ overrides (\ref{inheritanceA
ndOverriding}) an instance member $m_2$ and $m_1$ has a greater number of requi
red parameters than $m_2$. It is a static warning if an instance method $m_1$ ov
errides an instance member $m_2$ and $m_1$ has fewer positional parameters tha
n $m_2$. It is a static warning if an instance method $m_1$ overrides an insta
nce member $m_2$ and $m_1$ does not declare all the named parameters declared b
y $m_2$. |
| 1245 |
| 1246 % not quite right. It should be ok to override a method that requires N paramete
rs with one that requires M < N but accepts the others as optional. |
| 1247 |
| 1248 It is a static warning if an instance method $m_1$ overrides an instance member
$m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. It is a stati
c warning if an instance method $m_1$ overrides an instance member $m_2$, the s
ignature of $m_2$ explicitly specifies a default value for a formal parameter $p
$ and the signature of $m_1$ specifies a different default value for $p$. It is
a static warning if a class $C$ declares an instance method named $n$ and has a
setter named $n=$. It is a static warning if a class $C$ declares an instance me
thod named $n$ and an accessible static member named $n$ is declared in a superc
lass of $C$. |
| 1249 |
| 1250 % Works. If the name is public, no issue. If it's private, if a subclass has a c
onflicting inst var, it either is in the same lib and will be flagged, or is in
another and is not an issue. |
| 1251 |
| 1252 |
| 1253 \subsubsection{Operators} |
| 1254 \label{operators} |
| 1255 |
| 1256 {\em Operators} are instance methods with special names. |
| 1257 |
| 1258 \begin{grammar} |
| 1259 {\bf operatorSignature:} |
| 1260 returnType? \OPERATOR{} operator formalParameterList |
| 1261 . |
| 1262 |
| 1263 {\bf operator:}`\~{}'; |
| 1264 binaryOperator; |
| 1265 `[' `]' ; |
| 1266 `[' `]' `=' |
| 1267 . |
| 1268 |
| 1269 {\bf binaryOperator:}multiplicativeOperator; |
| 1270 additiveOperator; |
| 1271 shiftOperator; |
| 1272 relationalOperator; |
| 1273 `=='; |
| 1274 bitwiseOperator |
| 1275 . |
| 1276 \end{grammar} |
| 1277 |
| 1278 An operator declaration is identified using the built-in identifier (\ref{identi
fierReference}) \OPERATOR{}. |
| 1279 |
| 1280 The following names are allowed for user-defined operators: \code{$<$, $>$, $<$=
, $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$, []=, [], \~{}.} |
| 1281 |
| 1282 |
| 1283 It is a compile-time error if the arity of the user-declared operator \code{[]=}
is not 2. It is a compile-time error if the arity of a user-declared operator w
ith one of the names: \code{ $<$, $>$, $<$=, $>$=, ==, -, +, \~{}/, /, *, \%,
$|$, \^{}, \&, $<<$, $>>$, []} is not 1. It is a compile-time error if the arity
of the user-declared operator \code{-} is not 0 or 1. |
| 1284 |
| 1285 \commentary{ |
| 1286 The \code{-} operator is unique in that two overloaded versions are permitted. I
f the operator has no arguments, it denotes unary minus. If it has an argument,
it denotes binary subtraction. |
| 1287 } |
| 1288 |
| 1289 The name of the unary operator \code{-} is \code{unary-}. |
| 1290 |
| 1291 \rationale{ |
| 1292 This device allows the two methods to be distinguished for purposes of method lo
okup, override and reflection. |
| 1293 } |
| 1294 |
| 1295 It is a compile-time error if the arity of the user-declared operator \code{ \~
{}} is not 0. |
| 1296 |
| 1297 It is a compile-time error to declare an optional parameter in an operator. |
| 1298 |
| 1299 It is a static warning if the return type of the user-declared operator \code{[]
=} is explicitly declared and not \VOID{}. |
| 1300 |
| 1301 |
| 1302 \subsection{Getters} |
| 1303 \label{getters} |
| 1304 |
| 1305 Getters are functions (\ref{functions}) that are used to retrieve the values of
object properties. |
| 1306 |
| 1307 \begin{grammar} |
| 1308 {\bf getterSignature:} |
| 1309 type? \GET{} identifier |
| 1310 . |
| 1311 \end{grammar} |
| 1312 |
| 1313 %\Q{Why does a getter have a formal parameter list at all?} |
| 1314 |
| 1315 If no return type is specified, the return type of the getter is \DYNAMIC{}. |
| 1316 |
| 1317 A getter definition that is prefixed with the \STATIC{} modifier defines a stati
c getter. Otherwise, it defines an instance getter. The name of the getter is gi
ven by the identifier in the definition. |
| 1318 |
| 1319 %It is a compile-time error if a getter`s formal parameter list is not empty. |
| 1320 |
| 1321 The instance getters of a class $C$ are those instance getters declared by $C$,
either implicitly or explicitly, and the instance getters inherited by $C$ from
its superclass. The static getters of a class $C$ are those static getters decla
red by $C$. |
| 1322 |
| 1323 It is a compile-time error if a class has both a getter and a method with the sa
me name. This restriction holds regardless of whether the getter is defined expl
icitly or implicitly, or whether the getter or the method are inherited or not. |
| 1324 |
| 1325 \commentary{ |
| 1326 This implies that a getter can never override a method, and a method can never o
verride a getter or field. |
| 1327 } |
| 1328 |
| 1329 It is a static warning if a getter $m_1$ overrides (\ref{inheritanceAndOverridi
ng}) a getter |
| 1330 $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. It is a sta
tic warning if a class declares a static getter named $v$ and also has a non-st
atic setter named $v=$. It is a static warning if a class $C$ declares an instan
ce getter named $v$ and an accessible static member named $v$ or $v=$ is declare
d in a superclass of $C$. |
| 1331 |
| 1332 \subsection{Setters} |
| 1333 \label{setters} |
| 1334 |
| 1335 Setters are functions (\ref{functions}) that are used to set the values of objec
t properties. |
| 1336 |
| 1337 % what about top level ones? Same for getters |
| 1338 |
| 1339 \begin{grammar} |
| 1340 {\bf setterSignature:} |
| 1341 returnType? \SET{} identifier formalParameterList |
| 1342 . |
| 1343 \end{grammar} |
| 1344 |
| 1345 If no return type is specified, the return type of the setter is \DYNAMIC{}. |
| 1346 |
| 1347 A setter definition that is prefixed with the \STATIC{} modifier defines a stati
c setter. Otherwise, it defines an instance setter. The name of a setter is obt
ained by appending the string `=' to the identifier given in its signature. |
| 1348 |
| 1349 \commentary{Hence, a setter name can never conflict with, override or be overrid
den by a getter or method.} |
| 1350 |
| 1351 The instance setters of a class $C$ are those instance setters declared by $C$ e
ither implicitly or explicitly, and the instance setters inherited by $C$ from i
ts superclass. The static setters of a class $C$ are those static setters declar
ed by $C$. |
| 1352 |
| 1353 It is a compile-time error if a setter's formal parameter list does not consist
of exactly one required formal parameter $p$. \rationale{We could enforce this
via the grammar, but we`d have to specify the evaluation rules in that case.} |
| 1354 |
| 1355 %It is a compile-time error if a class has both a setter and a method with the s
ame name. This restriction holds regardless of whether the setter is defined exp
licitly or implicitly, or whether the setter or the method are inherited or not. |
| 1356 |
| 1357 It is a static warning if a setter declares a return type other than \VOID{}. |
| 1358 It is a static warning if a setter $m_1$ overrides (\ref{inheritanceAndOverridi
ng}) a setter $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$.
It is a static warning if a class has a setter named $v=$ with argument type $T
$ and a getter named $v$ with return type $S$, and $T$ may not be assigned to $S
$. It is a static warning if a class declares a static setter named $v=$ and al
so has a non-static member named $v$. It is a static warning if a class $C$ decl
ares an instance setter named $v=$ and an accessible static member named $v=$ or
$v$ is declared in a superclass of $C$. |
| 1359 |
| 1360 \subsection{Abstract Instance Members} |
| 1361 \label{abstractInstanceMembers} |
| 1362 |
| 1363 An {\em abstract method} (respectively, {\em abstract getter} or {\em abstract s
etter)} is an instance method, getter or setter that is not declared \EXTERNAL{}
and does not provide an implementation. An {\em concrete method} (respectively
, {\em concrete getter} or {\em concrete setter)} is an instance method, getter
or setter that is not abstract. |
| 1364 %The declaration of an abstract method is prefixed by the built-in identifier (\
ref{identifierReference}) \ABSTRACT{}. |
| 1365 |
| 1366 \rationale{ |
| 1367 Earlier versions of Dart required that abstract members be identified by prefixi
ng them with the modifier \ABSTRACT{}. The elimination of this requirement is m
otivated by the desire to use abstract classes as interfaces. Every Dart class i
nduces an implicit interface. |
| 1368 |
| 1369 Using an abstract class instead of an interface has important advantages. An abs
tract class can provide default implementations; it can also provide static meth
ods, obviating the need for service classes such as \code{Collections} or \code{
Lists}, whose entire purpose is to group utilities related to a given type. |
| 1370 |
| 1371 Eliminating the requirement for an explicit modifier on members makes abstract c
lasses more concise, making abstract classes an attractive substitute for inter
face declarations. |
| 1372 } |
| 1373 |
| 1374 \commentary {Invoking an abstract method, getter or setter results in an invocat
ion of \cd{noSuchMethod} exactly as if the declaration did not exist, unless a
suitable member $a$ is available in a superclass, in which case $a$ is invoked.
The normative specification for this appears under the definitions of lookup fo
r methods, getters and setters. |
| 1375 } |
| 1376 |
| 1377 % so does an abstract method override a method in a superclass or not? Does the
superclass method get inherited or not? This generally makes the spec inconsist
ent, as there is no simple answer. |
| 1378 % For example - if we say it does not override, then the superclass member is in
herited, in which case the rules for warning break down, and also there is quest
ion of whether there are two definitions of the same name. |
| 1379 % But if we do override, method lookup rules break down. So several things need
revisiting. |
| 1380 |
| 1381 \rationale{ |
| 1382 The purpose of an abstract method is to provide a declaration for purposes such
as type checking and reflection. In classes used as mixins, it is often useful t
o introduce such declarations for methods that the mixin expects will be provide
d by the superclass the mixin is applied to. |
| 1383 } |
| 1384 %always results in a run-time error. This must be \code{NoSuchMethodError} or an
instance of a subclass of \code{NoSuchMethodError}, such as \code{AbstractMetho
dError}. |
| 1385 |
| 1386 It is a static warning if an abstract member is declared or inherited in a concr
ete class unless that member overrides a concrete one. |
| 1387 |
| 1388 \rationale { |
| 1389 We wish to warn if one declares a concrete class with abstract members. However,
code like the following should work without warnings: |
| 1390 } |
| 1391 |
| 1392 \begin{dartCode} |
| 1393 class Base \{ |
| 1394 int get one =$>$ 1; |
| 1395 \} |
| 1396 |
| 1397 abstract class Mix \{ |
| 1398 int get one; |
| 1399 int get two =$>$ one + one; |
| 1400 \} |
| 1401 |
| 1402 class C extends Base with Mix \{ |
| 1403 \} |
| 1404 \} |
| 1405 \end{dartCode} |
| 1406 |
| 1407 \rationale{At run time, the concrete method \cd{one} declared in \cd{Base} will
be executed, and no problem should arise. Therefore no warning should be issued
and so we suppress warnings if a corresponding concrete member exists in the hie
rarchy. } |
| 1408 |
| 1409 \subsection{Instance Variables} |
| 1410 \label{instanceVariables} |
| 1411 |
| 1412 Instance variables are variables whose declarations are immediately contained wi
thin a class declaration and that are not declared \STATIC{}. The instance varia
bles of a class $C$ are those instance variables declared by $C$ and the instanc
e variables inherited by $C$ from its superclass. |
| 1413 |
| 1414 It is a compile-time error if an instance variable is declared to be constant. |
| 1415 |
| 1416 \rationale{ |
| 1417 The notion of a constant instance variable is subtle and confusing to programmer
s. |
| 1418 An instance variable is intended to vary per instance. A constant instance varia
ble would have the same value for all instances, and as such is already a dubiou
s idea. |
| 1419 |
| 1420 The language could interpret const instance variable declarations as instance ge
tters that return a constant. However, a constant instance variable could not b
e treated as a true compile time constant, as its getter would be subject to ove
rriding. |
| 1421 |
| 1422 Given that the value does not depend on the instance, it is better to use a sta
tic class variable. |
| 1423 An instance getter for it can always be defined manually if desired. |
| 1424 } |
| 1425 |
| 1426 |
| 1427 %An instance variable declaration of one of the forms \code{$T$ $v$;}, \code{\FI
NAL{} $T$ $v$;} , \code{$T$ $v$ = $e$;} , \code{\CONST{} $T$ $v$ = $e$;} or \c
ode{\FINAL{} $T$ $v$ = $e$;} always induces an implicit getter function (\ref{g
etters}) with signature |
| 1428 |
| 1429 %$T$ \GET{} $v$ |
| 1430 |
| 1431 %whose invocation evaluates to the value stored in $v$. |
| 1432 |
| 1433 %An instance variable declaration of one of the forms \code{\VAR{} $v$;}, \code
{\FINAL{} $v$;}, \code{\VAR{} $v$ = $e$;} , \code{\CONST{} $v$ = $e$;} or \code
{\FINAL{} $v$ = $e$;} always induces an implicit getter function with signatur
e |
| 1434 |
| 1435 %\GET{} $v$ |
| 1436 |
| 1437 %whose invocation evaluates to the value stored in $v$. |
| 1438 |
| 1439 %\commentary{Getters are introduced for all instance and static variables (\ref{
staticVariables}), regardless of whether they are const/final or not.} |
| 1440 |
| 1441 %A non-final instance variable declaration of the form \code{$T$ $v$;} or the f
orm \code{$T$ $v$ = $e$;} always induces an implicit setter function (\ref{se
tters}) with signature |
| 1442 |
| 1443 %\VOID{} \SET{} $v=(T$ $x)$ |
| 1444 |
| 1445 %whose execution sets the value of $v$ to the incoming argument $x$. |
| 1446 |
| 1447 %A non-final instance variable declaration of the form \code{\VAR{} $v$;} or th
e form \code{\VAR{} $v$ = $e$;} always induces an implicit setter function wi
th signature |
| 1448 |
| 1449 %\SET{} $v=(x)$ |
| 1450 |
| 1451 %whose execution sets the value of $v$ to the incoming argument $x$. |
| 1452 |
| 1453 |
| 1454 \subsection{Constructors} |
| 1455 \label{constructors} |
| 1456 |
| 1457 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}). |
| 1458 |
| 1459 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. |
| 1460 |
| 1461 |
| 1462 % 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. |
| 1463 |
| 1464 % The enclosing scope of a generative constructor is the instance scope of the c
lass in which it is declared (but what about redirecting?) |
| 1465 |
| 1466 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}. |
| 1467 |
| 1468 \subsubsection{Generative Constructors} |
| 1469 \label{generativeConstructors} |
| 1470 |
| 1471 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. |
| 1472 |
| 1473 \begin{grammar} |
| 1474 {\bf constructorSignature:} |
| 1475 identifier (`{\escapegrammar .}' identifier)? formalParameterList |
| 1476 . |
| 1477 \end{grammar} |
| 1478 |
| 1479 A {\em constructor parameter list} is a parenthesized, comma-separated list of f
ormal constructor parameters. A {\em formal constructor parameter} is either a f
ormal parameter (\ref{formalParameters}) or an initializing formal. An {\em init
ializing formal} has the form \code{\THIS{}.id}, where \code{id} is the name of
an instance variable of the immediately enclosing class. It is a compile-time er
ror if an initializing formal is used by a function other than a non-redirecting
generative constructor. |
| 1480 |
| 1481 If an explicit type is attached to the initializing formal, that is its static t
ype. Otherwise, the type of an initializing formal named \code{id} is $T_{id}$,
where $T_{id}$ is the type of the field named \code{id} in the immediately enclo
sing class. It is a static warning if the static type of \code{id} is not assign
able to $T_{id}$. |
| 1482 |
| 1483 Using an initializing formal \code{\THIS{}.id} in a formal parameter list does n
ot introduce a formal parameter name into the scope of the constructor. However,
the initializing formal does effect the type of the constructor function exactl
y as if a formal parameter named \code{id} of the same type were introduced in
the same position. |
| 1484 |
| 1485 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. |
| 1486 |
| 1487 |
| 1488 \commentary{ |
| 1489 The above rule allows initializing formals to be used as optional parameters: |
| 1490 } |
| 1491 |
| 1492 \begin{dartCode} |
| 1493 class A \{ |
| 1494 int x; |
| 1495 A([this.x]); |
| 1496 \} |
| 1497 \end{dartCode} |
| 1498 |
| 1499 \commentary{is legal, and has the same effect as} |
| 1500 |
| 1501 \begin{dartCode} |
| 1502 class A \{ |
| 1503 int x; |
| 1504 A([int x]): this.x = x; |
| 1505 \} |
| 1506 \end{dartCode} |
| 1507 |
| 1508 A {\em fresh instance} is an instance whose identity is distinct from any previ
ously allocated instance of its class. A generative constructor always operates
on a fresh instance of its immediately enclosing class. |
| 1509 |
| 1510 \commentary{ |
| 1511 The above holds if the constructor is actually run, as it is by \NEW{}. If a con
structor $c$ is referenced by \CONST{}, $c$ may not be run; instead, a canonical
object may be looked up. See the section on instance creation (\ref{instanceCre
ation}). |
| 1512 } |
| 1513 |
| 1514 If a generative constructor $c$ is not a redirecting constructor and no body is
provided, then $c$ implicitly has an empty body \code{\{\}}. |
| 1515 |
| 1516 |
| 1517 \paragraph{Redirecting Constructors} |
| 1518 \label{redirectingConstructors} |
| 1519 |
| 1520 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. |
| 1521 |
| 1522 \begin{grammar} |
| 1523 {\bf redirection:} |
| 1524 `{\escapegrammar :}' \THIS{} (`{\escapegrammar .}' identifier)? arguments |
| 1525 . |
| 1526 \end{grammar} |
| 1527 |
| 1528 % Need to specify exactly how executing a redirecting constructor works |
| 1529 |
| 1530 |
| 1531 %\Q{We now have generative constructors with no bodies as well.} |
| 1532 |
| 1533 \paragraph{Initializer Lists} |
| 1534 |
| 1535 An initializer list begins with a colon, and consists of a comma-separated list
of individual {\em initializers}. There are two kinds of initializers. |
| 1536 \begin{itemize} |
| 1537 \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. |
| 1538 |
| 1539 \item An {\em instance variable initializer} assigns a value to an individual in
stance variable. |
| 1540 \end{itemize} |
| 1541 |
| 1542 \begin{grammar} |
| 1543 {\bf initializers:} |
| 1544 `{\escapegrammar :}' superCallOrFieldInitializer (`,' superCallOrFieldInit
ializer)* |
| 1545 . |
| 1546 |
| 1547 |
| 1548 {\bf superCallOrFieldInitializer:}\SUPER{} arguments; |
| 1549 \SUPER{} `{\escapegrammar .}' identifier arguments; |
| 1550 fieldInitializer |
| 1551 . |
| 1552 |
| 1553 {\bf fieldInitializer:} |
| 1554 (\THIS{} `{\escapegrammar .}')? identifier `=' conditionalExpression casca
deSection* |
| 1555 . |
| 1556 |
| 1557 \end{grammar} |
| 1558 |
| 1559 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. |
| 1560 |
| 1561 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: |
| 1562 \begin{itemize} |
| 1563 \item Initialization at the declaration of $f$. |
| 1564 \item Initialization by means of an initializing formal of $k$. |
| 1565 \end{itemize} |
| 1566 |
| 1567 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. |
| 1568 |
| 1569 |
| 1570 \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. |
| 1571 } |
| 1572 |
| 1573 It is a compile-time error if a generative constructor of class \code{Object}
includes a superinitializer. |
| 1574 |
| 1575 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$. |
| 1576 |
| 1577 \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,. |
| 1578 } |
| 1579 |
| 1580 If $k$ is redirecting, then its redirect clause has the form |
| 1581 |
| 1582 \THIS{}$.g(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
| 1583 |
| 1584 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$. |
| 1585 |
| 1586 Otherwise, execution proceeds as follows: |
| 1587 |
| 1588 %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). |
| 1589 %Next, a |
| 1590 Any initializing formals declared in $k$'s parameter list are executed in the or
der they appear in the program text. |
| 1591 % In fact, this order is unobservable; this could be done any time prior to runn
ing the body, since |
| 1592 % these only effect \THIS{}. |
| 1593 Then, $k$'s initializers are executed in the order they appear in the program. |
| 1594 |
| 1595 \rationale {We could observe the order by side effecting external routines call
ed. So we need to specify the order.} |
| 1596 |
| 1597 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$. |
| 1598 |
| 1599 \rationale{ |
| 1600 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. |
| 1601 } |
| 1602 |
| 1603 Execution of an initializer of the form \code{\THIS{}.$v$ = $e$} proceeds as fol
lows: |
| 1604 |
| 1605 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$. |
| 1606 |
| 1607 An initializer of the form \code{$v$ = $e$} is equivalent to an initializer of t
he form \code{\THIS{}.$v$ = $e$}. |
| 1608 |
| 1609 Execution of a superinitializer of the form |
| 1610 |
| 1611 \SUPER{}$(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$ |
| 1612 |
| 1613 (respectively \SUPER{}$.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}:
a_{n+k})$ |
| 1614 |
| 1615 proceeds as follows: |
| 1616 |
| 1617 First, the argument list $(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}:
a_{n+k})$ is evaluated. |
| 1618 |
| 1619 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$. |
| 1620 |
| 1621 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$. |
| 1622 |
| 1623 It is a compile-time error if class $S$ does not declare a generative constructo
r named $S$ (respectively $S.id$) |
| 1624 |
| 1625 \subsubsection{Factories} |
| 1626 \label{factories} |
| 1627 |
| 1628 A {\em factory} is a constructor prefaced by the built-in identifier (\ref{iden
tifierReference}) \FACTORY{}. |
| 1629 |
| 1630 \begin{grammar} |
| 1631 {\bf factoryConstructorSignature:} |
| 1632 \FACTORY{} identifier (`{\escapegrammar .}' identifier)? formalParameter
List |
| 1633 . |
| 1634 \end{grammar} |
| 1635 |
| 1636 |
| 1637 %The enclosing scope of a factory constructor is the static scope \ref{} of the
class in which it is declared. |
| 1638 |
| 1639 The {\em return type} of a factory whose signature is of the form \FACTORY{} $M$
or the form \FACTORY{} $M.id$ is $M$ if $M$ is not a generic type; otherwise th
e return type is $M <T_1, \ldots, T_n>$ where $T_1, \ldots, T_n$ are the type p
arameters of the enclosing class |
| 1640 |
| 1641 It is a compile-time error if $M$ is not the name of the immediately enclosing c
lass. |
| 1642 |
| 1643 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. |
| 1644 |
| 1645 \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.} |
| 1646 |
| 1647 \rationale{Factories address classic weaknesses associated with constructors in
other languages. |
| 1648 Factories can produce instances that are not freshly allocated: they can come fr
om a cache. Likewise, factories can return instances of different classes. |
| 1649 |
| 1650 } |
| 1651 |
| 1652 \paragraph{Redirecting Factory Constructors} |
| 1653 \label{redirectingFactoryConstructors} |
| 1654 |
| 1655 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. |
| 1656 |
| 1657 \begin{grammar} |
| 1658 {\bf redirectingFactoryConstructorSignature:} |
| 1659 \CONST{}? \FACTORY{} identifier (`{\escapegrammar .}' identifier)? formalP
arameterList `=' type (`{\escapegrammar .}' identifier)? |
| 1660 . |
| 1661 \end{grammar} |
| 1662 |
| 1663 Calling a redirecting factory constructor $k$ causes the constructor $k^\prime$
denoted by $type$ (respectively, $type.identifier$) to be called with the actual
arguments passed to $k$, and returns the result of $k^\prime$ as the result of
$k$. The resulting constructor call is governed by the same rules as an instanc
e creation expression using \NEW{} (\ref{instanceCreation}). |
| 1664 |
| 1665 \commentary{ |
| 1666 It follows that if $type$ or $type.id$ are not defined, or do not refer to a cla
ss or constructor, a dynamic error occurs, as with any other undefined construct
or call. The same holds if $k$ is called with fewer required parameters or more
positional parameters than $k^\prime$ expects, or if $k$ is called with a named
parameter that is not declared by $k^\prime$. |
| 1667 } |
| 1668 |
| 1669 It is a compile-time error if $k$ explicitly specifies a default value for an op
tional parameter.\commentary{ |
| 1670 Default values specified in $k$ would be ignored, since it is the {\em actual} p
arameters that are passed to $k^\prime$. Hence, default values are disallowed. |
| 1671 } |
| 1672 |
| 1673 It is a compile-time error if a redirecting factory constructor redirects to its
elf, either directly or indirectly via a sequence of redirections. %does not red
irect to a non-redirecting factory constructor or to a generative constructor in
a finite number of steps. |
| 1674 |
| 1675 \rationale{ |
| 1676 If a redirecting factory $F_1$ redirects to another redirecting factory $F_2$ an
d $F_2$ then redirects to $F_1$, then both $F_1$ and $F_2$ are ill-defined. Such
cycles are therefore illegal. |
| 1677 } |
| 1678 |
| 1679 |
| 1680 It is a static warning if $type$ does not denote a class accessible in the curre
nt scope; if $type$ does denote such a class $C$ it is a static warning if the r
eferenced constructor (be it $type$ or $type.id$) is not a constructor of $C$. |
| 1681 |
| 1682 \commentary{ |
| 1683 Note that it is not possible to modify the arguments being passed to $k'$. |
| 1684 } |
| 1685 % but we have the same issue with other redirecting constructors, no?) |
| 1686 \rationale{ |
| 1687 At first glance, one might think that ordinary factory constructors could simply
create instances of other classes and return them, and that redirecting factori
es are unnecessary. However, redirecting factories have several advantages: |
| 1688 \begin{itemize} |
| 1689 \item An abstract class may provide a constant constructor that utilizes the con
stant constructor of another class. |
| 1690 \item A redirecting factory constructors avoids the need for forwarders to repea
t the default values for formal parameters in their signatures. |
| 1691 %\item A generic factory class that aggregates factory constructors for types it
does not implement can still have its type arguments passed correctly. |
| 1692 \end{itemize} |
| 1693 |
| 1694 %An example of the latter point: |
| 1695 %} |
| 1696 |
| 1697 |
| 1698 %\begin{dartCode} |
| 1699 %\CLASS{} W$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { W(w) {...} ...} |
| 1700 %\CLASS{} X$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { X(x) {...} ...} |
| 1701 %\CLASS{} Y$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { Y(y) {...} ...} |
| 1702 %\CLASS{} Z$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { Z(z) {...} ...} |
| 1703 |
| 1704 |
| 1705 %\CLASS{} F$<$T$>$ { // note that F does not implement A |
| 1706 % \STATIC{} F$<$T$>$ idw(w) $=>$ \NEW{} W$<$T$>$(w); // illegal - T not in sco
pe in idw |
| 1707 % \FACTORY{} F.idx(x) $=>$ \NEW{} X$<$T$>$(x); |
| 1708 % \FACTORY{} F.idy(y) $=>$ \NEW{} Y$<$T$>$(y); |
| 1709 % \STATIC{} F idz(z) $=>$ \NEW{} Z(z); // does not capture the type argument |
| 1710 %} |
| 1711 |
| 1712 %\CLASS{} A$<$T$>${ |
| 1713 % \FACTORY{} A.idw(w) $=>$ F$<$T$>$.idw(w); |
| 1714 %// illegal - cannot pass type parameter to static method |
| 1715 % \FACTORY{} A.idx(x) $=> \NEW{} $F$<$T$>$.idx(x); // works, but allocates a gr
atuitous instance of F |
| 1716 % \FACTORY{} A.idy(y) = Y$<$T$>$; // works |
| 1717 % \FACTORY{} A.idz(z) $=>$ F.idz(z); // wrong - returns Z$<$Dynamic$>$; no way
to pass type argument |
| 1718 } |
| 1719 %\end{dartCode} |
| 1720 |
| 1721 It is a compile-time error if $k$ is prefixed with the \CONST{} modifier but $k^
\prime$ is not a constant constructor (\ref{constantConstructors}). |
| 1722 |
| 1723 It is a static warning if the function type of $k^\prime$ is not a subtype of th
e type of $k$. |
| 1724 |
| 1725 \commentary{ |
| 1726 This implies that the resulting object conforms to the interface of the immedia
tely enclosing class of $k$. |
| 1727 } |
| 1728 |
| 1729 It is a static type warning if any of the type arguments to $k^\prime$ are not s
ubtypes of the bounds of the corresponding formal type parameters of $type$. |
| 1730 |
| 1731 |
| 1732 \subsubsection{Constant Constructors} |
| 1733 \label{constantConstructors} |
| 1734 |
| 1735 A {\em constant constructor} may be used to create compile-time constant (\ref{
constants}) objects. A constant constructor is prefixed by the reserved word \CO
NST{}. |
| 1736 |
| 1737 \begin{grammar} |
| 1738 {\bf constantConstructorSignature:} |
| 1739 \CONST{} qualified formalParameterList |
| 1740 . |
| 1741 \end{grammar} |
| 1742 |
| 1743 |
| 1744 %\commentary{Spell out subtleties: a constant constructor call within the initia
lizer of a constant constructor is treated as a ordinary constructor call (a ne
w), because the arguments cannot be assumed constant anymore. In practice, this
means two versions are compiled and analyzed. One for new and one for const.} |
| 1745 |
| 1746 % \Q{How to specify?} |
| 1747 |
| 1748 \commentary{All the work of a constant constructor must be handled via its initi
alizers.} |
| 1749 |
| 1750 It is a compile-time error if a constant constructor is declared by a class that
has a non-final instance variable. |
| 1751 |
| 1752 \commentary{ |
| 1753 The above refers to both locally declared and inherited instance variables. |
| 1754 } |
| 1755 |
| 1756 The superinitializer that appears, explicitly or implicitly, in the initializer
list of a constant constructor must specify a constant constructor of the superc
lass of the immediately enclosing class or a compile-time error occurs. |
| 1757 |
| 1758 Any expression that appears within the initializer list of a constant constructo
r must be a potentially constant expression, or a compile-time error occurs. |
| 1759 |
| 1760 A {\em potentially constant expression} is an expression $e$ that would be a val
id constant expression if all formal parameters of $e$'s immediately enclosing c
onstant constructor were treated as compile-time constants that were guaranteed
to evaluate to an integer, boolean or string value as required by their immediat
ely enclosing superexpression. |
| 1761 |
| 1762 \commentary{ |
| 1763 The difference between a potentially constant expression and a compile-time cons
tant expression (\ref{const}) deserves some explanation. |
| 1764 |
| 1765 The key issue is whether one treats the formal parameters of a constructor as co
mpile-time constants. |
| 1766 |
| 1767 If a constant constructor is invoked from a constant object expression, the actu
al arguments will be required to be compile-time constants. Therefore, if we wer
e assured that constant constructors were always invoked from constant object ex
pressions, we could assume that the formal parameters of a constructor were comp
ile-time constants. |
| 1768 |
| 1769 However, constant constructors can also be invoked from ordinary instance creati
on expressions (\ref{new}), and so the above assumption is not generally valid. |
| 1770 |
| 1771 Nevertheless, the use of the formal parameters of a constant constructor within
the constructor is of considerable utility. The concept of potentially constant
expressions is introduced to facilitate limited use of such formal parameters. S
pecifically, we allow the usage of the formal parameters of a constant construct
or for expressions that involve built-in operators, but not for constant objects
, lists and maps. This allows for constructors such as: |
| 1772 } |
| 1773 |
| 1774 \begin{dartCode} |
| 1775 \CLASS{} C \{ |
| 1776 \FINAL{} x; \FINAL{} y; \FINAL{} z; |
| 1777 \CONST{} C(p, q): x = q, y = p + 100, z = p + q; |
| 1778 % what about |
| 1779 % \CONST{} C(p, q): x = q, y = p + 100, z = p + 'foo'; |
| 1780 % perhaps moot. Current spec says that would be ok; type checker can worry, as
can execution, which is at compile time anyway |
| 1781 \} |
| 1782 \end{dartCode} |
| 1783 |
| 1784 \commentary{ |
| 1785 The assignment to \code{x} is allowed under the assumption that \code{q} is a co
mpile-time constant (even though \code{q} is not, in general a compile-time cons
tant). The assignment to \code{y} is similar, but raises additional questions.
In this case, the superexpression of \code{p} is \code{p + 100}, and it requires
that \code{p} be a numeric compile-time constant for the entire expression to b
e considered constant. The wording of the specification allows us to assume tha
t \code{p} evaluates to an integer. A similar argument holds for \code{p} and \c
ode{q} in the assignment to \code{z}. |
| 1786 |
| 1787 However, the following constructors are disallowed: |
| 1788 } |
| 1789 |
| 1790 \begin{dartCode} |
| 1791 \CLASS{} D \{ |
| 1792 \FINAL{} w; |
| 1793 \CONST{} D.makeList(p): w = \CONST{} [p]; // compile-time error |
| 1794 \CONST{} D.makeMap(p): w = \CONST{} \{``help'': q\}; // compile-time error |
| 1795 \CONST{} D.makeC(p): w = \CONST{} C(p, 12); // compile-time error |
| 1796 \} |
| 1797 \end{dartCode} |
| 1798 |
| 1799 \commentary{ |
| 1800 The problem is not that the assignments to \code{w} are not potentially constant
; they are. However, all these run afoul of the rules for constant lists (\ref{
lists}), maps (\ref{maps}) and objects (\ref{const}), all of which independently
require their subexpressions to be constant expressions. |
| 1801 } |
| 1802 |
| 1803 \rationale{ |
| 1804 All of the illegal constructors of \code{D} above could not be sensibly invoked
via \NEW{}, because an expression that must be constant cannot depend on a forma
l parameter, which may or may not be constant. In contrast, the legal examples m
ake sense regardless of whether the constructor is invoked via \CONST{} or via \
NEW{}. |
| 1805 |
| 1806 Careful readers will of course worry about cases where the actual arguments to \
code{C()} are constants, but are not numeric. This is precluded by the following
rule, combined with the rules for evaluating constant objects (\ref{const}). |
| 1807 } |
| 1808 |
| 1809 When invoked from a constant object expression, a constant constructor must thro
w an exception if any of its actual parameters is a value that would prevent one
of the potentially constant expressions within it from being a valid compile-ti
me constant. |
| 1810 |
| 1811 %Discuss External Constructors in ne subsubsection here |
| 1812 |
| 1813 \subsection{Static Methods} |
| 1814 \label{staticMethods} |
| 1815 |
| 1816 {\em Static methods} are functions, other than getters or setters, whose declara
tions are immediately contained within a class declaration and that are declared
\STATIC{}. The static methods of a class $C$ are those static methods declared
by $C$. |
| 1817 |
| 1818 \rationale{ |
| 1819 Inheritance of static methods has little utility in Dart. Static methods cannot
be overridden. Any required static function can be obtained from its declaring l
ibrary, and there is no need to bring it into scope via inheritance. Experience
shows that developers are confused by the idea of inherited methods that are not
instance methods. |
| 1820 |
| 1821 Of course, the entire notion of static methods is debatable, but it is retained
here because so many programmers are familiar with it. Dart static methods may b
e seen as functions of the enclosing library. |
| 1822 } |
| 1823 |
| 1824 It is a static warning if a class $C$ declares a static method named $n$ and has
a setter named $n=$. |
| 1825 %It is a static warning if a class has a static method with the same name as a s
tatic member of one of its superclasses. |
| 1826 |
| 1827 %\rationale{ |
| 1828 %This last restriction makes classes more brittle with respect to changes in the
class hierarchy. It stems from a general observation that shadowing of names in
the same scope is questionable and should elicit a warning. |
| 1829 %} |
| 1830 %\commentary{ |
| 1831 %There is no hiding of static methods, or of static variables. |
| 1832 %} |
| 1833 |
| 1834 |
| 1835 \subsection{Static Variables} |
| 1836 \label{staticVariables} |
| 1837 |
| 1838 {\em Static variables} are variables whose declarations are immediately containe
d within a class declaration and that are declared \STATIC{}. The static variabl
es of a class $C$ are those static variables declared by $C$. |
| 1839 |
| 1840 %A static variable declaration of one of the forms \code{\STATIC{} $T$ $v$;},
\code{\STATIC{} $T$ $v$ = $e$;} , \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} or
\code{\STATIC{} \FINAL{} $T$ $v$ = $e$;} always induces an implicit static gette
r function (\ref{getters}) with signature |
| 1841 |
| 1842 %\STATIC{} $T$ \GET{} $v$ |
| 1843 |
| 1844 %whose invocation evaluates as described below (\ref{evaluationOfStaticVariableG
etters}).%to the value stored in $v$. |
| 1845 |
| 1846 |
| 1847 %A static variable declaration of one of the forms \code{\STATIC{} \VAR{} $v$;}
, \code{\STATIC{} \VAR{} $v$ = $e$;} , \code{\STATIC{} \CONST{} $v$ = $e$;} or
\code{\STATIC{} \FINAL{} $v$ = $e$;} always induces an implicit static getter
function with signature |
| 1848 |
| 1849 %\STATIC{} \GET{} $v$ |
| 1850 |
| 1851 %whose invocation evaluates as described below (\ref{evaluationOfStaticVariable
Getters}).%to the value stored in $v$. |
| 1852 |
| 1853 %A non-final static variable declaration of the form \code{\STATIC{} $T$ $v$;}
or the form \code{\STATIC{} $T$ $v$ = $e$;} always induces an implicit static
setter function (\ref{setters}) with signature |
| 1854 |
| 1855 %\STATIC{} \VOID{} \SET{} $v=(T$ $x)$ |
| 1856 |
| 1857 %whose execution sets the value of $v$ to the incoming argument $x$. |
| 1858 |
| 1859 %A static variable declaration of the form \code{\STATIC{} \VAR{} $v$;} or the
form \code{\STATIC{} \VAR{} $v$ = $e$;} always induces an implicit static set
ter function with signature |
| 1860 |
| 1861 %\STATIC{} \SET{} $v=(x)$ |
| 1862 |
| 1863 %whose execution sets the value of $v$ to the incoming argument $x$. |
| 1864 |
| 1865 %Extrernal static functions, getters, setters |
| 1866 |
| 1867 %\subsubsection{Evaluation of Implicit Static Variable Getters} |
| 1868 %\label{evaluationOfStaticVariableGetters} |
| 1869 |
| 1870 %Let $d$ be the declaration of a static variable $v$. The implicit getter method
of $v$ executes as follows: |
| 1871 %\begin{itemize} |
| 1872 %\item If $d$ is of one of the forms \code{\STATIC{} \VAR{} $v$ = $e$;} , \code{
\STATIC{} $T$ $v$ = $e$; }, \code{\STATIC{} \FINAL{} $v$ = $e$; } or \code{\STAT
IC{} \FINAL{} $T$ $v$ = $e$;} and no value has yet been stored into $v$ then the
initializer expression $e$ is evaluated. If, during the evaluation of $e$, the
getter for $v$ is referenced, a \code{CyclicInitializationError} is thrown. If t
he evaluation succeeded yielding an object $o$, let $r = o$, otherwise let $r =
\NULL{}$. In any case, $r$ is stored into $v$. The result of executing the gette
r is $r$. |
| 1873 %\item If $d$ is of one of the forms \code{\STATIC{} \CONST{} $v$ = $e$; } or \
code{\STATIC{} \CONST{} $T$ $v$ = $e$;} the result of the getter is the value of
the compile time constant $e$. |
| 1874 %Otherwise |
| 1875 %\item The result of executing the getter method is the value stored in $v$. |
| 1876 %\end{itemize} |
| 1877 |
| 1878 |
| 1879 |
| 1880 \subsection{Superclasses} |
| 1881 \label{superclasses} |
| 1882 |
| 1883 The superclass of a class $C$ that has a with clause \code{\WITH{} $M_1, \ldots,
M_k$} and an extends clause \code{\EXTENDS{} S} is the application of mixin (\r
ef{mixins}) $M_k* \cdots * M_1$ to S. If no with clause is specified then the
\EXTENDS{} clause of a class $C$ specifies its superclass. If no \EXTENDS{} cla
use is specified, then either: |
| 1884 \begin{itemize} |
| 1885 \item $C$ is \code{Object}, which has no superclass. OR |
| 1886 \item Class $C$ is deemed to have an \EXTENDS{} clause of the form \code{\EXTEN
DS{} Object}, and the rules above apply. |
| 1887 \end{itemize} |
| 1888 |
| 1889 It is a compile-time error to specify an \EXTENDS{} clause for class \code{Objec
t}. |
| 1890 |
| 1891 \begin{grammar} |
| 1892 {\bf superclass:} |
| 1893 \EXTENDS{} type |
| 1894 . |
| 1895 \end{grammar} |
| 1896 |
| 1897 %The superclass clause of a class C is processed within the enclosing scope of t
he static scope of C. |
| 1898 %\commentary{ |
| 1899 %This means that in a generic class, the type parameters of the generic are avai
lable in the superclass clause. |
| 1900 %} |
| 1901 |
| 1902 %It is a compile-time error if the \EXTENDS{} clause of a class $C$ includes a
type expression that does not denote a class available in the lexical scope of $
C$. |
| 1903 It is a compile-time error if the \EXTENDS{} clause of a class $C$ specifies a
malformed type as a superclass. |
| 1904 % too strict? Do we e want extends List<Undeclared> to work as List<dynamic>? |
| 1905 |
| 1906 \commentary{ The type parameters of a generic class are available in the lexical
scope of the superclass clause, potentially shadowing classes in the surroundin
g scope. The following code is therefore illegal and should cause a compile-time
error: |
| 1907 } |
| 1908 |
| 1909 \begin{dartCode} |
| 1910 class T \{\} |
| 1911 |
| 1912 /* Compilation error: Attempt to subclass a type parameter */ |
| 1913 class G$<$T$>$ extends T \{\} |
| 1914 |
| 1915 \end{dartCode} |
| 1916 |
| 1917 |
| 1918 A class $S$ is {\em a superclass} of a class $C$ iff either: |
| 1919 \begin{itemize} |
| 1920 \item $S$ is the superclass of $C$, or |
| 1921 \item $S$ is a superclass of a class $S^{\prime}$ and $S^{\prime}$ is a supercla
ss of $C$. |
| 1922 \end{itemize} |
| 1923 |
| 1924 It is a compile-time error if a class $C$ is a superclass of itself. |
| 1925 |
| 1926 |
| 1927 |
| 1928 |
| 1929 \subsubsection{Inheritance and Overriding} |
| 1930 \label{inheritanceAndOverriding} |
| 1931 |
| 1932 |
| 1933 %A class $C$ {\em inherits} any accessible instance members of its superclass t
hat are not overridden by members declared in $C$. |
| 1934 |
| 1935 Let $C$ be a class, let $A$ be a superclass of $C$, and let $S_1 \ldots S_k$ b
e superclasses of $C$ that are also subclasses of $A$. $C$ {\em inherits} all ac
cessible instance members of $A$ that have not been overridden by a declaratio
n in $C$ or in at least one of $S_1 \ldots S_k$. |
| 1936 |
| 1937 \rationale { |
| 1938 It would be more attractive to give a purely local definition of inheritance, t
hat depended only on the members of the direct superclass $S$. However, a class
$C$ can inherit a member $m$ that is not a member of its superclass $S$. This
can occur when the member $m$ is private |
| 1939 to the library $L_1$ of $C$, whereas $S$ comes from a different library $L_2$, b
ut |
| 1940 the superclass chain of $S$ includes a class declared in $L_1$. |
| 1941 } |
| 1942 |
| 1943 A class may override instance members that would otherwise have been inherited f
rom its superclass. |
| 1944 |
| 1945 Let $C = S_0$ be a class declared in library $L$, and let $\{S_1 \ldots S_k\}$ b
e the set of all superclasses of $C$, where $S_i$ is the superclass of $S_{i-1}$
for $i \in 1 .. k$. Let $C$ declare a member $m$, and let $m^\prime$ be a memb
er of $S_j, j \in 1 .. k$, that has the same name as $m$, such that $m^\prime$
is accessible to $L$. Then $m$ overrides $m^\prime$ if $m^\prime$ is not alrea
dy overridden by a member of at least one of $S_1 \ldots S_{j-1}$ and neither $m
$ nor $m^\prime$ are fields. |
| 1946 |
| 1947 %Let $C$ be a class declared in library $L$, with superclass $S$ and let $C$ dec
lare an instance member $m$, and assume $S$ declares an instance member $m^\pri
me$ with the same name as $m$. Then $m$ {\em overrides} $m^\prime$ iff $m^\prime
$ is accessible (\ref{privacy}) to $L$, $m$ has the same name as $m^\prime$ an
d neither $m$ nor $m^\prime$ are fields. |
| 1948 |
| 1949 \commentary{Fields never override each other. The getters and setters induced by
fields do.} |
| 1950 |
| 1951 \rationale{Again, a local definition of overriding would be preferable, but fail
s to account for library privacy. |
| 1952 } |
| 1953 |
| 1954 Whether an override is legal or not is described elsewhere in this specification
(see \ref{instanceMethods}, \ref{getters} and \ref{setters}). |
| 1955 |
| 1956 \commentary{For example getters may not legally override methods and vice versa.
Setters never override methods or getters, and vice versa, because their names
always differ. |
| 1957 } |
| 1958 |
| 1959 \rationale{ |
| 1960 It is nevertheless convenient to define the override relation between members in
this way, so that we can concisely describe the illegal cases. |
| 1961 } |
| 1962 |
| 1963 \commentary{ |
| 1964 Note that instance variables do not participate in the override relation, but th
e getters and setters they induce do. Also, getters don`t override setters and v
ice versa. Finally, static members never override anything. |
| 1965 } |
| 1966 |
| 1967 It is a static warning if a non-abstract class inherits an abstract method. |
| 1968 |
| 1969 \commentary { |
| 1970 For convenience, here is a summary of the relevant rules. Remember that this is
not normative. The controlling language is in the relevant sections of the speci
fication. |
| 1971 |
| 1972 \begin{enumerate} |
| 1973 |
| 1974 \item There is only one namespace for getters, setters, methods and constructors
(\ref{scoping}). A field $f$ introduces a getter $f$ and a setter $f=$ (\ref{in
stanceVariables}, \ref{staticVariables}). When we speak of members here, we mean
accessible fields, getters, setters and methods (\ref{classes}). |
| 1975 \item You cannot have two members with the same name in the same class - be the
y declared or inherited (\ref{scoping}, \ref{classes}). |
| 1976 \item Static members are never inherited. |
| 1977 \item It is a warning if you have an static member named $m$ in your class or a
ny superclass (even though it is not inherited) and an instance member of the s
ame name (\ref{instanceMethods}, \ref{getters}, \ref{setters}). |
| 1978 \item It is a warning if you have a static setter $v=$, and an instance member $
v$ (\ref{setters}). |
| 1979 \item It is a warning if you have a static getter $v$ and an instance setter $v=
$ (\ref{getters}). |
| 1980 \item If you define an instance member named $m$, and your superclass has an in
stance member of the same name, they override each other. This may or may not be
legal. |
| 1981 \item \label{typeSigAssignable} |
| 1982 If two members override each other, it is a static warning if their type signatu
res are not assignable to each other (\ref{instanceMethods}, \ref{getters}, \ref
{setters}) (and since these are function types, this means the same as "subtype
s of each other"). |
| 1983 \item \label{requiredParams} |
| 1984 If two members override each other, it is a static warning if the overriding mem
ber has more required parameters than the overridden one (\ref{instanceMethods}
). |
| 1985 \item \label{optionalPositionals} |
| 1986 If two members override each other, it is a static warning if the overriding mem
ber has fewer positional parameters than the the overridden one (\ref{instanceM
ethods}). |
| 1987 \item \label{namedParams} |
| 1988 If two members override each other, it is a static warning if the overriding mem
ber does not have all the named parameters that the the overridden one has (\ref
{instanceMethods}). |
| 1989 \item Setters, getters and operators never have optional parameters of any kind;
it's a compile-time error (\ref{operators}, \ref{getters}, \ref{setters}). |
| 1990 \item It is a compile-time error if a member has the same name as its enclosing
class (\ref{classes}). |
| 1991 \item A class has an implicit interface (\ref{classes}). |
| 1992 \item Superinterface members are not inherited by a class, but are inherited by
its implicit interface. Interfaces have their own inheritance rules (\ref{interf
aceInheritanceAndOverriding}). |
| 1993 \item A member is abstract if it has no body and is not labeled \EXTERNAL{} (\re
f{abstractInstanceMembers}, \ref{externalFunctions}). |
| 1994 \item A class is abstract iff it is explicitly labeled \ABSTRACT{}.% or if it de
clares (not just inherits) an abstract member (\ref{classes}). |
| 1995 \item It is a static warning a concrete class has an abstract member (declared o
r inherited). |
| 1996 \item It is a static warning and a dynamic error to call a non-factory construct
or of an abstract class (\ref{new}). |
| 1997 \item If a class defines an instance member named $m$, and any of its superinter
faces have a member named $m$, the interface of the class overrides $m$. |
| 1998 \item An interface inherits all members of its superinterfaces that are not ov
erridden and not members of multiple superinterfaces. |
| 1999 \item If multiple superinterfaces of an interface define a member with the same
name $m$, then at most one member is inherited. That member (if it exists) is t
he one whose type is a subtype of all the others. If there is no such member, th
en: |
| 2000 \begin{itemize} |
| 2001 \item A static warning is given. |
| 2002 \item If possible the interface gets a member named $m$ that has the minimum
number of required parameters among all the members in the superinterfaces, the
maximal number of positionals, and the superset of named parameters. The typ
es of these are all \DYNAMIC{}. If this is impossible then no member $m$ appears
in the interface. |
| 2003 \end{itemize} (\ref{interfaceInheritanceAndOverriding}) |
| 2004 \item Rule \ref{typeSigAssignable} applies to interfaces as well as classes (\
ref{interfaceInheritanceAndOverriding}). |
| 2005 \item It is a static warning if a concrete class does not have an implementatio
n for a method in any of its superinterfaces unless it declares its own \cd{n
oSuchMethod} method (\ref{superinterfaces}). |
| 2006 \item The identifier of a named constructor cannot be the same as the name of a
member declared (as opposed to inherited) in the same class (\ref{constructors})
. |
| 2007 \end{enumerate} |
| 2008 } |
| 2009 |
| 2010 |
| 2011 %Can we have abstract getters and setters? |
| 2012 |
| 2013 \subsection{Superinterfaces} |
| 2014 \label{superinterfaces} |
| 2015 % what about rules about classes that fail to implement their interfaces? |
| 2016 |
| 2017 A class has a set of direct superinterfaces. This set includes the interface of
its superclass and the interfaces specified in the the \IMPLEMENTS{} clause of
the class. |
| 2018 % and any superinterfaces specified by interface injection (\ref{interfaceInject
ion}). \Q{The latter needs to be worded carefully - when do interface injection
clauses execute and in what scope?} |
| 2019 |
| 2020 \begin{grammar} |
| 2021 {\bf interfaces:} |
| 2022 \IMPLEMENTS{} typeList |
| 2023 . |
| 2024 \end{grammar} |
| 2025 |
| 2026 It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifie
s a type variable as a superinterface. It is a compile-time error if the \IMPL
EMENTS{} clause of a class $C$ specifies a malformed type as a superinterface
It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies
type \DYNAMIC{} as a superinterface. It is a compile-time error if the \IMPLEM
ENTS{} clause of a class $C$ specifies a type $T$ as a superinterface more than
once. |
| 2027 It is a compile-time error if the superclass of a class $C$ is specified as a su
perinterface of $C$. |
| 2028 |
| 2029 \rationale{ |
| 2030 One might argue that it is harmless to repeat a type in the superinterface list,
so why make it an error? The issue is not so much that the situation described
in program source is erroneous, but that it is pointless. As such, it is an indi
cation that the programmer may very well have meant to say something else - and
that is a mistake that should be called to her or his attention. Nevertheless,
we could simply issue a warning; and perhaps we should and will. That said, prob
lems like these are local and easily corrected on the spot, so we feel justified
in taking a harder line. |
| 2031 } |
| 2032 |
| 2033 It is a compile-time error if the interface of a class $C$ is a superinterface o
f itself. |
| 2034 |
| 2035 Let $C$ be a concrete class that does not declare its own \code{noSuchMethod()}
method. |
| 2036 It is a static warning if the implicit interface of $C$ includes an instance me
mber $m$ of type $F$ and $C$ does not declare or inherit a corresponding instanc
e member $m$ of type $F'$ such that $F' <: F$. |
| 2037 |
| 2038 \commentary{A class does not inherit members from its superinterfaces. However,
its implicit interface does. |
| 2039 } |
| 2040 |
| 2041 |
| 2042 \rationale { |
| 2043 We choose to issue these warnings only for concrete classes; an abstract class m
ight legitimately be designed with the expectation that concrete subclasses will
implement part of the interface. |
| 2044 We also disable these warnings if a \code{noSuchMethod()} declaration is present
. In such cases, the supported interface is going to be implemented via \code{no
SuchMethod()} and no actual declarations of the implemented interface's members
are needed. This allows proxy classes for specific types to be implemented witho
ut provoking type warnings. |
| 2045 } |
| 2046 |
| 2047 It is a static warning if the implicit interface of a class $C$ includes an ins
tance member $m$ of type $F$ and $C$ declares or inherits a corresponding instan
ce member $m$ of type $F'$ if $F'$ is not a subtype of $F$. |
| 2048 |
| 2049 \rationale{ |
| 2050 However, if a class does explicitly declare a member that conflicts with its sup
erinterface, this always yields a static warning. |
| 2051 |
| 2052 } |
| 2053 %It is a static warning if an imported superinterface of a class $C$ declares pr
ivate members. |
| 2054 |
| 2055 % Should we ignore unimplemented private members? |
| 2056 |
| 2057 %\rationale{This last rule is problematic. As code evolves in one library ($L_1$
) it may add private members to a class $I_1$ implemented or inherited in anothe
r library $L_2$ breaking $L_1$. This is a direct result of coupling an interfa
ce based type system with library based privacy. We are considering alternative
semantics that might help resolve this issue. |
| 2058 %} |
| 2059 |
| 2060 %\commentary{However, it is perfectly acceptable if a type mentioned in the impl
ements clause is mentioned as a superinterface in an interface injection clause.
|
| 2061 %} |
| 2062 |
| 2063 %\rationale{We disallow repetition of a type in a given implements clause, as th
at is a localized mistake. However, separate clauses (that is the original class
and various injections) may evolve separately over time, and we don't want to c
ause breakage. For example |
| 2064 |
| 2065 %class C implements I1 {...}; // class declaration |
| 2066 |
| 2067 |
| 2068 %somewhere someone realizes that C could implement I2 class C implements I2; //
injection |
| 2069 |
| 2070 %later, the author of C decides to support I2 |
| 2071 |
| 2072 %class C implements I1, I2 {...}; // class declaration |
| 2073 |
| 2074 %this should not cause breakage. |
| 2075 %} |
| 2076 |
| 2077 % \rationale{This avoids the issues with so-called miranda methods etc. } |
| 2078 |
| 2079 |
| 2080 \section{Interfaces} |
| 2081 \label{interfaces} |
| 2082 |
| 2083 An {\em interface} defines how one may interact with an object. An interface has
methods, getters and setters and a set of superinterfaces. |
| 2084 |
| 2085 \subsection{Superinterfaces} |
| 2086 \label{interfaceSuperinterfaces} |
| 2087 |
| 2088 An interface has a set of direct superinterfaces. |
| 2089 |
| 2090 An interface $J$ is a superinterface of an interface $I$ iff either $J$ is a dir
ect superinterface of $I$ or $J$ is a superinterface of a direct superinterface
of $I$. |
| 2091 |
| 2092 |
| 2093 |
| 2094 |
| 2095 \subsubsection{Inheritance and Overriding} |
| 2096 \label{interfaceInheritanceAndOverriding} |
| 2097 |
| 2098 Let $J$ be an interface and $K$ be a library. We define $inherited(J, K)$ to be
the set of members $m$ such that all of the following hold: |
| 2099 \begin{itemize} |
| 2100 \item $m$ is accessible to $K$ and |
| 2101 \item $A$ is a direct superinterface of $J$ and either |
| 2102 \begin{itemize} |
| 2103 \item $m$ is a member of $A$ or |
| 2104 \item $m$ is a member of $inherited(A, K)$. |
| 2105 \end{itemize} |
| 2106 \item $m$ is not overridden by $J$. |
| 2107 \end{itemize} |
| 2108 |
| 2109 Furthermore, we define $overrides(J, K)$ to be the set of members $m^\prime$ su
ch that all of the following hold: |
| 2110 \begin{itemize} |
| 2111 \item $J$ is the implicit interface of a class $C$. |
| 2112 \item $C$ declares a member $m$. |
| 2113 \item $m^\prime$ has the same name as $m$. |
| 2114 \item $m^\prime$ is accessible to $K$. |
| 2115 \item $A$ is a direct superinterface of $J$ and either |
| 2116 \begin{itemize} |
| 2117 \item $m^\prime$ is a member of $A$ or |
| 2118 \item $m^\prime$ is a member of $inherited(A, K)$. |
| 2119 \end{itemize} |
| 2120 \end{itemize} |
| 2121 |
| 2122 |
| 2123 Let $I$ be the implicit interface of a class $C$ declared in library $L$. $I$ {
\em inherits} all members of $inherited(I, L)$ and $I$ {\em overrides} $m^\prime
$ if $m^\prime \in overrides(I, L)$. |
| 2124 |
| 2125 |
| 2126 %Let $I = S_0$ be the implicit interface of a class $C$ declared in library $L$,
and let $\{S_1 \ldots S_k\}$ be the set of all superinterfaces of $I$. |
| 2127 |
| 2128 %Let $I$ be the implicit interface of a class $C$. $I$ inherits any instance me
mbers of its superinterfaces that are not overridden by members declared in $C$.
|
| 2129 |
| 2130 % tighten definition? do we need chain as for classes? Definition for interface
override? |
| 2131 |
| 2132 However, if the above rules would cause multiple members $m_1, \ldots, m_k$ wit
h the same name $n$ to be inherited (because identically named members existed i
n several superinterfaces) then at most one member is inherited. |
| 2133 |
| 2134 %If some but not all of the $m_i, 1 \le i \le k$ are getters, or if some but not
all of the $m_i$ are setters, none of the $m_i$ are inherited, and a static war
ning is issued. |
| 2135 |
| 2136 Otherwise, if the static types $T_1, \ldots, T_k$ of the members $m_1, \ldots,
m_k$ are not identical, then there must be a member $m_x$ such that $T_x <: T_
i, 1 \le x \le k$ for all $i \in 1..k$, or a static type warning occurs. The m
ember that is inherited is $m_x$, if it exists; otherwise: |
| 2137 \begin{itemize} |
| 2138 \item Let $numberOfPositionals(f)$ denote the number of positional parameters of
a function $f$, and let $numberOfRequiredParams(f)$ denote the number of requir
ed parameters of a function $f$. Furthermore, let $s$ denote the set of all name
d parameters of the $m_1, \ldots, m_k$. Then let |
| 2139 |
| 2140 $h = max(numberOfPositionals(m_i)), $ |
| 2141 |
| 2142 $r = min(numberOfRequiredParams(m_i)), i \in 1..k$. |
| 2143 |
| 2144 If $r \le h$ then $I$ has a method named $n$, with $r$ required parameters of ty
pe \DYNAMIC{}, $h$ positional parameters of type \DYNAMIC{}, named parameters $
s$ of type \DYNAMIC{} and return type \DYNAMIC{}. |
| 2145 \item Otherwise none of the members $m_1, \ldots, m_k$ is inherited. |
| 2146 \end{itemize} |
| 2147 |
| 2148 \commentary{The only situation where the runtime would be concerned with this wo
uld be during reflection, if a mirror attempted to obtain the signature of an in
terface member. |
| 2149 } |
| 2150 |
| 2151 \rationale{ |
| 2152 The current solution is a tad complex, but is robust in the face of type annotat
ion changes. Alternatives: (a) No member is inherited in case of conflict. (b)
The first m is selected (based on order of superinterface list) (c) Inherited me
mber chosen at random. |
| 2153 |
| 2154 (a) means that the presence of an inherited member of an interface varies depend
ing on type signatures. (b) is sensitive to irrelevant details of the declarati
on and (c) is liable to give unpredictable results between implementations or ev
en between different compilation sessions. |
| 2155 } |
| 2156 |
| 2157 \section{Mixins} |
| 2158 \label{mixins} |
| 2159 |
| 2160 |
| 2161 A mixin describes the difference between a class and its superclass. A mixin is
always derived from an existing class declaration. |
| 2162 |
| 2163 It is a compile-time error if a declared or derived mixin refers to \SUPER{}. It
is a compile-time error if a declared or derived mixin explicitly declares a co
nstructor. It is a compile-time error if a mixin is derived from a class whose s
uperclass is not \code{Object}. |
| 2164 |
| 2165 \rationale{ |
| 2166 These restrictions are temporary. We expect to remove them in later versions of
Dart. |
| 2167 |
| 2168 The restriction on the use of \SUPER{} avoids the problem of rebinding \SUPER{}
when the mixin is bound to difference superclasses. |
| 2169 |
| 2170 The restriction on constructors simplifies the construction of mixin application
s because the process of creating instances is simpler. |
| 2171 |
| 2172 The restriction on the superclass means that the type of a class from which a m
ixin is derived is always implemented by any class that mixes it in. This allows
us to defer the question of whether and how to express the type of the mixin in
dependently of its superclass and super interface types. |
| 2173 |
| 2174 Reasonable answers exist for all these issues, but their implementation is non-t
rivial. |
| 2175 } |
| 2176 |
| 2177 \subsection{Mixin Application} |
| 2178 \label{mixinApplication} |
| 2179 |
| 2180 A mixin may be applied to a superclass, yielding a new class. Mixin application
occurs when a mixin is mixed into a class declaration via its \WITH{} clause. T
he mixin application may be used to extend a class per section (\ref{classes});
alternately, a class may be defined as a mixin application as described in this
section. |
| 2181 |
| 2182 \begin{grammar} |
| 2183 {\bf mixinApplicationClass:} |
| 2184 identifier typeParameters? `=' mixinApplication `{\escapegrammar ;}' . |
| 2185 |
| 2186 {\bf mixinApplication:} |
| 2187 type mixins interfaces? |
| 2188 . |
| 2189 \end{grammar} |
| 2190 |
| 2191 A mixin application of the form \code{$S$ \WITH{} $M$;} defines a class $C$ w
ith superclass $S$. |
| 2192 |
| 2193 A mixin application of the form \code{$S$ \WITH{} $M_1, \ldots, M_k$;} defines
a class $C$ whose superclass is the application of the mixin composition (\ref
{mixinComposition}) $M_{k-1} * \ldots * M_1$ to $S$. |
| 2194 |
| 2195 In both cases above, $C$ declares the same instance members as $M$ (respectively
, $M_k$). If any of the instance fields of $M$ (respectively, $M_k$) have initia
lizers, they are executed in the scope of $M$ (respectively, $M_k$) to initializ
e the corresponding fields of $C$. |
| 2196 |
| 2197 For each generative constructor named $q_i(T_{i1}$ $ a_{i1}, \ldots , T_{ik_i}$
$ a_{ik_i}), i \in 1..n$ of $S$, $C$ has an implicitly declared constructor name
d |
| 2198 $q'_i = [C/S]q_i$ of the form |
| 2199 |
| 2200 $q'_i(a_{i1}, \ldots , a_{ik_i}):\SUPER(a_{i1}, \ldots , a_{ik_i});$. |
| 2201 |
| 2202 % The types must be given in the copied constructor. It was tempting to elide th
em; after all, checked mode will catch things in the |
| 2203 % super call - but this may be a problem for tools. |
| 2204 % We interpret this instead as S includes the generic parameters, so the signat
ure has already substituted them. |
| 2205 % Default values may not be replicable for optional params due to scoping/privac
y. |
| 2206 % How to describe and implement |
| 2207 |
| 2208 %The class $C$ has an implicitly declared nullary generative constructor with no
initializer list and no body. |
| 2209 |
| 2210 If the mixin application declares support for interfaces, the resulting class im
plements those interfaces. |
| 2211 |
| 2212 It is a compile-time error if $S$ is a malformed type. It is a compile-time erro
r if $M$ (respectively, any of $M_1, \ldots, M_k$) is a malformed type. It is a
compile time error if a well formed mixin cannot be derived from $M$ (respective
ly, from each of $M_1, \ldots, M_k$). |
| 2213 |
| 2214 Let $K$ be a class declaration with the same constructors, superclass and inter
faces as $C$, and the instance members declared by $M$ (respectively $M_1, \ldo
ts, M_k$). It is a static warning if the declaration of $K$ would cause a static
warning. It is a compile-time error if the declaration of $K$ would cause a co
mpile-time error. |
| 2215 |
| 2216 \commentary{ |
| 2217 If, for example, $M$ declares an instance member $im$ whose type is at odds with
the type of a member of the same name in $S$, this will result in a static warn
ing just as if we had defined $K$ by means of an ordinary class declaration exte
nding $S$, with a body that included $im$. |
| 2218 |
| 2219 %Another implication of this definition is that one cannot apply a mixin to a su
perclass that does not provide a nullary constructor. |
| 2220 } |
| 2221 |
| 2222 The effect of a class definition of the form \code{\CLASS{} $C$ = $M$; } or the
form |
| 2223 \code{\CLASS{} $C<T_1, \ldots, T_n>$ = $M$; } in library $L$ is to introduce t
he name $C$ into the scope of $L$, bound to the class (\ref{classes}) defined by
the mixin application $M$. The name of the class is also set to $C$. Iff the c
lass is prefixed by the built-in identifier \ABSTRACT{}, the class being defined
is an abstract class. |
| 2224 |
| 2225 |
| 2226 \subsection{Mixin Composition} |
| 2227 \label{mixinComposition} |
| 2228 |
| 2229 \rationale{ |
| 2230 Dart does not directly support mixin composition, but the concept is useful when
defining how the superclass of a class with a mixin clause is created. |
| 2231 } |
| 2232 |
| 2233 The {\em composition of two mixins}, $M_1<T_1 \ldots T_{k_{M_1}}>$ and $M_2<U_1
\ldots U_{k_{M_2}}>$, written $M_1<T_1 \ldots T_{k_{M_1}}> * M_2<U_1 \ldots U_
{k_{M_2}}>$ defines an anonymous mixin such that for any class $S<V_1 \ldots V_{
k_S}>$, the application of $M_1<T_1 \ldots T_{k_{M_1}}> * M_2<U_1 \ldots U_{k_{
M_2}}>$ to $S<V_1 \ldots V_{k_S}>$ is equivalent to |
| 2234 |
| 2235 \code{\ABSTRACT{} \CLASS{} $Id_1<T_1 \ldots T_{k_{M_1}}, U_1 \ldots U_{k_{M_2}
}, V_1 \ldots V_{k_S}> = Id_2<U_1 \ldots U_{k_{M_2}}, V_1 \ldots V_{k_S}>$ \W
ITH{} $M_1 <T_1 \ldots T_{k_{M_1}}>$;} |
| 2236 |
| 2237 where $Id_2$ denotes |
| 2238 |
| 2239 \code{\ABSTRACT{} \CLASS{} $Id_2<U_1 \ldots U_{k_{M_2}}, V_1 \ldots V_{k_S}> =
S<V_1 \ldots V_{k_S}>$ \WITH{} $M_2<U_1 \ldots U_{k_{M_2}}>$; } |
| 2240 |
| 2241 and $Id_1$ and $Id_2$ are unique identifiers that do not exist anywhere in the p
rogram. |
| 2242 |
| 2243 \rationale{ |
| 2244 The classes produced by mixin composition are regarded as abstract because they
cannot be instantiated independently. They are only introduced as anonymous supe
rclasses of ordinary class declarations and mixin applications. Consequently, no
warning is given if a mixin composition includes abstract members, or incomplet
ely implements an interface. |
| 2245 } |
| 2246 |
| 2247 Mixin composition is associative. |
| 2248 |
| 2249 |
| 2250 \commentary{ |
| 2251 Note that any subset of $M_1$, $M_2$ and $S$ may or may not be generic. For any
non-generic declaration, the corresponding type parameters may be elided, and if
no type parameters remain in the derived declarations $Id_1$ and/or $Id_2$ then
the those declarations need not be generic either. |
| 2252 } |
| 2253 |
| 2254 |
| 2255 \section{Generics} |
| 2256 \label{generics} |
| 2257 |
| 2258 A class declaration (\ref{classes}) or type alias (\ref{typedef}) |
| 2259 $G$ may be {\em generic}, that is, $G$ may have formal type parameters declared.
A generic declaration induces a family of declarations, one for each set of act
ual type parameters provided in the program. |
| 2260 |
| 2261 \begin{grammar} |
| 2262 {\bf typeParameter:} |
| 2263 metadata identifier (\EXTENDS{} type)? |
| 2264 . |
| 2265 {\bf typeParameters:} |
| 2266 `<' typeParameter (`,' typeParameter)* `>' |
| 2267 . |
| 2268 \end{grammar} |
| 2269 |
| 2270 A type parameter $T$ may be suffixed with an \EXTENDS{} clause that specifies th
e {\em upper bound} for $T$. If no \EXTENDS{} clause is present, the upper boun
d is \code{Object}. It is a static type warning if a type parameter is a supert
ype of its upper bound. The bounds of type variables are a form of type annotati
on and have no effect on execution in production mode. |
| 2271 |
| 2272 The type parameters of a generic $G$ are in scope in the bounds of all of the ty
pe parameters of $G$. The type parameters of a generic class declaration $G$ are
also in scope in the \EXTENDS{} and \IMPLEMENTS{} clauses of $G$ (if these exis
t) and in the body of $G$. However, a type parameter is considered to be a mal
formed type when referenced by a static member. |
| 2273 |
| 2274 \rationale{ |
| 2275 The restriction is necessary since a type variable has no meaning in the context
of a static member, because statics are shared among all instantiations of a ge
neric. However, a type variable may be referenced from an instance initializer,
even though \THIS{} is not available. |
| 2276 } |
| 2277 |
| 2278 \commentary{ |
| 2279 Because type parameters are in scope in their bounds, we support F-bounded quant
ification (if you don't know what that is, don't ask). This enables typechecking
code such as: |
| 2280 } |
| 2281 |
| 2282 \begin{dartCode} |
| 2283 \INTERFACE{} Ordered$<$T$>$ \{ |
| 2284 operator $>$ (T x); |
| 2285 \} |
| 2286 |
| 2287 \CLASS{} Sorter$<$T \EXTENDS{} Ordered$<$T$>>$ \{ |
| 2288 sort(List$<$T$>$ l) {... l[n] $<$ l[n+1] ...} |
| 2289 \} |
| 2290 |
| 2291 \end{dartCode} |
| 2292 |
| 2293 \commentary{ |
| 2294 Even where type parameters are in scope there are numerous restrictions at this
time: |
| 2295 \begin{itemize} |
| 2296 \item A type parameter cannot be used to name a constructor in an instance creat
ion expression (\ref{instanceCreation}). |
| 2297 \item A type parameter cannot be used as a superclass or superinterface (\ref{su
perclasses}, \ref{superinterfaces}, \ref{interfaceSuperinterfaces}). |
| 2298 \end{itemize} |
| 2299 |
| 2300 The normative versions of these are given in the appropriate sections of this s
pecification. Some of these restrictions may be lifted in the future. |
| 2301 } |
| 2302 |
| 2303 %A generic has a type parameter scope. The enclosing scope of a type parameter s
cope of a generic G is the enclosing scope of G. |
| 2304 |
| 2305 |
| 2306 %class T {...} |
| 2307 |
| 2308 %class G<T> extends T; |
| 2309 |
| 2310 %By current rules, this is illegal. Make sure we preserve this. |
| 2311 |
| 2312 |
| 2313 %\subsection{Interface Injection} |
| 2314 %\label{interfaceInjection} |
| 2315 |
| 2316 %An {\em interface injection declaration} causes a pre-existing class $S$ to be
considered a subinterface of another interface $I$. It is a static type warning
if $S$ is not a structural subtype of $I$. However, the subinterface relations i
mplied by the interface injection declaration are considered to hold by both the
typechecker and the runtime, regardless. |
| 2317 |
| 2318 %\begin{grammar} |
| 2319 %classInterfaceInjection: |
| 2320 %class qualified typeParameters? interfaces '{\escapegrammar ;}' |
| 2321 % . |
| 2322 |
| 2323 |
| 2324 %interfaceInterfaceInjection: |
| 2325 %interface qualified typeParameters? superinterfaces '{\escapegrammar ;}' |
| 2326 %. |
| 2327 %\end{grammar} |
| 2328 |
| 2329 %\rationale{Since subinterface relations can be tested dynamically via \IS{}, in
terface injection is not just a directive to the static checker. The dynamic rel
ations implied must hold regardless of whether a static typecheck has succeeded
, or has been performed at all. This makes sense from the perspective of preserv
ing programmer intent. The injection describes a nominal type relation that the
programmer wishes to hold. Just as a supertype mentioned within a class declarat
ion is considered a supertype even though type errors might arise among (say) ov
erridden and overriding methods, so it must be that the relation implied by an i
njection holds regardless of type errors. |
| 2330 %In addition, this decision helps to produce meaningful and localized error mess
ages. Any errors are reported at the point of injection rather than at program p
oints that rely on the relation (a well known problem with structural subtyping
in OO systems). |
| 2331 %} |
| 2332 |
| 2333 %\Q{When does an interface injection take effect? When the containing library is
loaded? |
| 2334 %What is the scope of such a declaration? Is it global, or only in the scope of
the containing library? The scope of such a declaration is global. |
| 2335 %An injection must be at top level. Who has the right to inject an interface $I$
into another class $C$? Anybody? But since this affects dynamic behavior, is th
is a weird security issue? |
| 2336 %The current theory is that there is no security within an isolate, and one can
never refer to a type from another isolate, so supposedly not an issue. This ass
umption (no mutually suspicious code in the same isolate) is suspect but it seem
s there is nothing to be done at this point. |
| 2337 %If libs are first class, they get created dynamically in order, and new libs mi
ght modify the type relations among other libs types - but then it is clear when
that happened and order is ok. |
| 2338 %} |
| 2339 |
| 2340 %It is a compile-time error if a type $T$ appears more than once in the implemen
ts or eextends clause of an interface injection. |
| 2341 |
| 2342 |
| 2343 \section{Metadata} |
| 2344 \label{metadata} |
| 2345 |
| 2346 Dart supports metadata which is used to attach user defined annotations to progr
am structures. |
| 2347 |
| 2348 \begin{grammar} |
| 2349 {\bf metadata:} |
| 2350 (`@' qualified ({\escapegrammar `.'} identifier)? (arguments)?)* |
| 2351 . |
| 2352 \end{grammar} |
| 2353 |
| 2354 Metadata consists of a series of annotations, each of which begin with the chara
cter @, followed by a constant expression that starts with an identifier. It is
a compile time error if the expression is not one of the following: |
| 2355 \begin{itemize} |
| 2356 \item A reference to a compile-time constant variable. |
| 2357 \item The name of a class. |
| 2358 \item A call to a constant constructor. |
| 2359 \end{itemize} |
| 2360 |
| 2361 Metadata is associated with the abstract syntax tree of the program construct $p
$ that immediately follows the metadata, assuming $p$ is not itself metadata or
a comment. Metadata can be retrieved at runtime via a reflective call, provided
the annotated program construct $p$ is accessible via reflection. |
| 2362 |
| 2363 \commentary{ |
| 2364 Reflective access to metadata is not yet implemented as of the M4 release. |
| 2365 |
| 2366 Obviously, metadata can also be retrieved statically by parsing the program and
evaluating the constants via a suitable interpreter. In fact many if not most us
es of metadata are entirely static. |
| 2367 } |
| 2368 |
| 2369 \rationale{ |
| 2370 It is important that no runtime overhead be incurred by the introduction of meta
data that is not actually used. Because metadata only involves constants, the ti
me at which it is computed is irrelevant so that implementations may skip the me
tadata during ordinary parsing and execution and evaluate it lazily. |
| 2371 } |
| 2372 |
| 2373 \commentary{ |
| 2374 It is possible to associate metadata with constructs that may not be accessible
via reflection, such as local variables (though it is conceivable that in the fu
ture, richer reflective libraries might provide access to these as well). This
is not as useless as it might seem. As noted above, the data can be retrieved st
atically if source code is available. |
| 2375 } |
| 2376 |
| 2377 Metadata can appear before a library, class, typedef, type parameter, constructo
r, factory, function, field, parameter, or variable declaration and before an im
port or export directive. |
| 2378 |
| 2379 The constant expression given in an annotation is type checked and evaluated in
the scope surrounding the declaration being annotated. |
| 2380 |
| 2381 |
| 2382 \section{Expressions} |
| 2383 \label{expressions} |
| 2384 |
| 2385 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}). |
| 2386 |
| 2387 |
| 2388 \begin{grammar} |
| 2389 |
| 2390 {\bf expression:}assignableExpression assignmentOperator expression; |
| 2391 conditionalExpression cascadeSection*; |
| 2392 throwExpression |
| 2393 . |
| 2394 |
| 2395 |
| 2396 {\bf expressionWithoutCascade:}assignableExpression assignmentOperator expressio
nWithoutCascade; |
| 2397 conditionalExpression; |
| 2398 throwExpressionWithoutCascade |
| 2399 . |
| 2400 |
| 2401 {\bf expressionList:} |
| 2402 expression (`,' expression)* %should these be top level expressions? |
| 2403 . |
| 2404 \end{grammar} |
| 2405 |
| 2406 \begin{grammar} |
| 2407 {\bf primary:}thisExpression; |
| 2408 \SUPER{} assignableSelector; |
| 2409 functionExpression; |
| 2410 literal; |
| 2411 identifier; |
| 2412 newExpression; |
| 2413 constObjectExpression; |
| 2414 `(' expression `)' |
| 2415 . |
| 2416 |
| 2417 \end{grammar} |
| 2418 |
| 2419 An expression $e$ may always be enclosed in parentheses, but this never has any
semantic effect on $e$. |
| 2420 |
| 2421 \commentary{ |
| 2422 Sadly, it may have an effect on the surrounding expression. Given a class $C$ wi
th static method $m => 42$, $C.m()$ returns 42, but $(C).m()$ produces a \code{N
oSuchMethodError}. This anomaly can be corrected by ensuring that every instanc
e of \code{Type} has instance members corresponding to its static members. This
issue may be addressed in future versions of Dart . |
| 2423 } |
| 2424 |
| 2425 \subsubsection{Object Identity} |
| 2426 \label{objectIdentity} |
| 2427 |
| 2428 The predefined Dart function \cd{identical()} is defined such that \code{identic
al($c_1$, $c_2$)} iff: |
| 2429 \begin{itemize} |
| 2430 \item $c_1$ evaluates to either \NULL{} or an instance of \code{bool} and \co
de{$c_1$ == $c_2$}, OR |
| 2431 \item $c_1$ and $c_2$ are instances of \code{int} and \code{$c_1$ == $c_2$}, OR |
| 2432 \item $c_1$ and $c_2$ are constant strings and \code{$c_1$ == $c_2$}, OR |
| 2433 \item $c_1$ and $c_2$ are instances of \cd{double} and one of the following
holds: |
| 2434 \begin{itemize} |
| 2435 \item $c_1$ and $c_2$ are non-zero and \code{$c_1$ == $c_2$}. |
| 2436 \item Both $c_1$ and $c_2$ are $+0.0$. |
| 2437 \item Both $c_1$ and $c_2$ are $-0.0$. |
| 2438 \item Both $c_1$ and $c_2$ represent a NaN value. |
| 2439 \end{itemize} |
| 2440 OR |
| 2441 \item $c_1$ and $c_2$ are constant lists that are defined to be identical in th
e specification of literal list expressions (\ref{lists}), OR |
| 2442 \item $c_1$ and $c_2$ are constant maps that are defined to be identical in the
specification of literal map expressions (\ref{maps}), OR |
| 2443 \item $c_1$ and $c_2$ are constant objects of the same class $C$ and each membe
r field of $c_1$ is identical to the corresponding field of $c_2$. OR |
| 2444 \item $c_1$ and $c_2$ are the same object. |
| 2445 \end{itemize} |
| 2446 |
| 2447 \commentary{ |
| 2448 The definition of \cd{identity} for doubles differs from that of equality in tha
t a NaN is equal to itself, and that negative and positive zero are distinct. |
| 2449 } |
| 2450 |
| 2451 \rationale{ |
| 2452 The definition of equality for doubles is dictated by the IEEE 754 standard, whi
ch posits that NaNs do not obey the law of reflexivity. Given that hardware imp
lements these rules, it is necessary to support them for reasons of efficiency. |
| 2453 |
| 2454 The definition of identity is not constrained in the same way. Instead, it assum
es that bit-identical doubles are identical. |
| 2455 |
| 2456 The rules for identity make it impossible for a Dart programmer to observe wheth
er a boolean or numerical value is boxed or unboxed. |
| 2457 } |
| 2458 |
| 2459 |
| 2460 \subsection{Constants} |
| 2461 \label{constants} |
| 2462 |
| 2463 A {\em constant expression} is an expression whose value can never change, and t
hat can be evaluated entirely at compile time. |
| 2464 |
| 2465 A constant expression is one of the following: |
| 2466 \begin{itemize} |
| 2467 \item A literal number (\ref{numbers}). |
| 2468 \item A literal boolean (\ref{booleans}). |
| 2469 \item A literal string (\ref{strings}) where any interpolated expression (\ref{
stringInterpolation}) is a compile-time constant that evaluates to a numeric, st
ring or boolean value or to \NULL{}. |
| 2470 \rationale{It would be tempting to allow string interpolation where the interpol
ated value is any compile-time constant. However, this would require running th
e \code{toString()} method for constant objects, which could contain arbitrary c
ode.} |
| 2471 \item A literal symbol (\ref{symbols}). |
| 2472 \item \NULL{} (\ref{null}). |
| 2473 \item A qualified reference to a static constant variable (\ref{variables}). \co
mmentary {For example, If class C declares a constant static variable v, C.v is
a constant. The same is true if C is accessed via a prefix p; p.C.v is a constan
t. |
| 2474 } |
| 2475 \item An identifier expression that denotes a constant variable, class or a type
alias. |
| 2476 \item A constant constructor invocation (\ref{const}). |
| 2477 \item A constant list literal (\ref{lists}). |
| 2478 \item A constant map literal (\ref{maps}). |
| 2479 \item A simple or qualified identifier denoting a top-level function (\ref{funct
ions}) or a static method (\ref{staticMethods}). |
| 2480 \item A parenthesized expression \code{($e$)} where $e$ is a constant expression
. |
| 2481 \item An expression of the form \code{identical($e_1$, $e_2$)} where $e_1$ and $
e_2$ are constant expressions and \code{identical()} is statically bound to the
predefined dart function \code{identical()} discussed above (\ref{objectIdent
ity}). |
| 2482 \item An expression of one of the forms \code{$e_1$ == $e_2$} or \code{$e_1$ !
= $e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numer
ic, string or boolean value or to \NULL{}. |
| 2483 \item An expression of one of the forms \code{!$e$}, \code{$e_1$ \&\& $e_2$} or
\code{$e_1 || e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that e
valuate to a boolean value. |
| 2484 \item An expression of one of the forms \~{}$e$, $e_1$ \^{} $e_2$, \code{$e_1$ \
& $e_2$}, $e_1 | e_2$, $e_1 >> e_2$ or $e_1 << e_2$, where $e$, $e_1$ and $e_2
$ are constant expressions that evaluate to an integer value or to \NULL{}. |
| 2485 \item An expression of one of the forms \code{$-e$}, \code{$e_1 + e_2$}, \code{
$e_1$ - $e_2$}, \code{$e_1$ * $e_2$}, \code{$e_1$ / $e_2$,} \code{$e_1$ \~{}/ $e
_2$}, \code{$e_1 > e_2$}, \code{$e_1 < e_2$}, \code{$e_1$ $>$= $e_2$}, \cod
e{$e_1$ $<$= $e_2$} or \code{$e_1$ \% $e_2$}, where $e$, $e_1$ and $e_2$ are co
nstant expressions that evaluate to a numeric value or to \NULL{}. |
| 2486 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where where $e_1$, $e_2$
and $e_3$ are constant expressions and $e_1$ evaluates to a boolean value. |
| 2487 \end{itemize} |
| 2488 |
| 2489 % null in all the expressions |
| 2490 |
| 2491 % designed so constants do not depend on check diode being on or not. |
| 2492 |
| 2493 It is a compile-time error if an expression is required to be a constant express
ion but its evaluation would raise an exception. |
| 2494 |
| 2495 % so, checked mode? analyzers? editor/development compilers? |
| 2496 \commentary{ |
| 2497 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. |
| 2498 |
| 2499 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. |
| 2500 |
| 2501 On the other hand, since implementations are free to compile code late, some com
pile-time errors may manifest quite late. |
| 2502 } |
| 2503 |
| 2504 \begin{dartCode} |
| 2505 \CONST{} x = 1/0; |
| 2506 \FINAL{} y = 1/0; |
| 2507 |
| 2508 \CLASS{} K \{ |
| 2509 m1() \{ |
| 2510 \VAR{} z = \FALSE{}; |
| 2511 \IF{} (z) \{\RETURN{} x; \} |
| 2512 \ELSE{} \{ \RETURN{} 2;\} |
| 2513 \} |
| 2514 |
| 2515 m2() \{ |
| 2516 \IF{} (\TRUE{}) \{\RETURN{} y; \} |
| 2517 \ELSE{} \{ \RETURN{} 3;\} |
| 2518 \} |
| 2519 |
| 2520 \} |
| 2521 |
| 2522 \end{dartCode} |
| 2523 |
| 2524 \commentary{An implementation is free to immediately issue a compilation error f
or \code{x}, but it is not required to do so. It could defer errors if it does
not immediately compile the declarations that reference \code{x}. For example,
it could delay giving a compilation error about the method \code{m1} until the f
irst invocation of \code{m1}. However, it could not choose to execute \code{m1},
see that the branch that refers to \code{x} is not taken and return 2 successf
ully. |
| 2525 |
| 2526 The situation with respect to an invocation \code{m2} is different. Because \cod
e{y} is not a compile-time constant (even though its value is), one need not giv
e a compile-time error upon compiling \code{m2}. An implementation may run the c
ode, which will cause the getter for \code{y} to be invoked. At that point, the
initialization of \code{y} must take place, which requires the initializer to b
e compiled, which will cause a compilation error. |
| 2527 } |
| 2528 |
| 2529 \rationale{ |
| 2530 The treatment of \NULL{} merits some discussion. Consider \code{\NULL{} + 2}. T
his expression always causes an error. We could have chosen not to treat it as a
constant expression (and in general, not to allow \NULL{} as a subexpression of
numeric or boolean constant expressions). There are two arguments for includin
g it: |
| 2531 \begin{enumerate} |
| 2532 \item It is constant. We can evaluate it at compile-time. |
| 2533 \item It seems more useful to give the error stemming from the evaluation explic
itly. |
| 2534 \end{enumerate} |
| 2535 } |
| 2536 |
| 2537 It is a compile-time error if the value of a compile-time constant expression de
pends on itself. |
| 2538 |
| 2539 \commentary{ |
| 2540 As an example, consider: |
| 2541 } |
| 2542 |
| 2543 \begin{dartCode} |
| 2544 \CLASS{} CircularConsts\{ |
| 2545 // Illegal program - mutually recursive compile-time constants |
| 2546 \STATIC{} \CONST{} i = j; // a compile-time constant |
| 2547 \STATIC{} \CONST{} j = i; // a compile-time constant |
| 2548 \} |
| 2549 \end{dartCode} |
| 2550 |
| 2551 |
| 2552 \begin{grammar} |
| 2553 {\bf literal:}nullLiteral; |
| 2554 booleanLiteral; |
| 2555 numericLiteral; |
| 2556 stringLiteral; |
| 2557 symbolLiteral; |
| 2558 mapLiteral; |
| 2559 listLiteral |
| 2560 . |
| 2561 \end{grammar} |
| 2562 |
| 2563 |
| 2564 |
| 2565 \subsection{Null} |
| 2566 \label{null} |
| 2567 |
| 2568 The reserved word \NULL{} denotes the {\em null object}. |
| 2569 %\Q{Any methods, such as \code{isNull}?} |
| 2570 |
| 2571 \begin{grammar} |
| 2572 {\bf nullLiteral:} |
| 2573 \NULL{} |
| 2574 . |
| 2575 \end{grammar} |
| 2576 |
| 2577 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 or implement \code{Null}. |
| 2578 Invoking a method on \NULL{} yields a \code{NoSuchMethodError} unless the metho
d is explicitly implemented by class \code{Null}. |
| 2579 |
| 2580 The static type of \NULL{} is $\bot$. |
| 2581 |
| 2582 \rationale{The decision to use $\bot$ instead of \code{Null} allows \NULL{} to b
e be assigned everywhere without complaint by the static checker. |
| 2583 } |
| 2584 |
| 2585 |
| 2586 \subsection{Numbers} |
| 2587 \label{numbers} |
| 2588 |
| 2589 A {\em numeric literal} is either a decimal or hexadecimal integer of arbitrary
size, or a decimal double. |
| 2590 |
| 2591 \begin{grammar} |
| 2592 {\bf numericLiteral:}NUMBER; |
| 2593 HEX\_NUMBER |
| 2594 . |
| 2595 |
| 2596 {\bf NUMBER:} DIGIT+ (`{\escapegrammar.}' DIGIT+)? EXPONENT?; |
| 2597 {`\escapegrammar .}' DIGIT+ EXPONENT? |
| 2598 . |
| 2599 |
| 2600 {\bf EXPONENT:} |
| 2601 (`e' $|$ `E') ('+' $|$ `-`)? DIGIT+ |
| 2602 . |
| 2603 |
| 2604 {\bf HEX\_NUMBER:}`0x' HEX\_DIGIT+; |
| 2605 `0X' HEX\_DIGIT+ |
| 2606 . |
| 2607 |
| 2608 {\bf HEX\_DIGIT:}`a'{\escapegrammar ..}'f'; |
| 2609 `A'{\escapegrammar ..}'F'; |
| 2610 DIGIT |
| 2611 . |
| 2612 \end{grammar} |
| 2613 |
| 2614 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 does not include a decimal point it d
enotes a decimal integer. Otherwise, the numeric literal denotes a 64 bit doub
le precision floating point number as specified by the IEEE 754 standard. |
| 2615 |
| 2616 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. |
| 2617 |
| 2618 \commentary{ |
| 2619 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. |
| 2620 } |
| 2621 |
| 2622 It is a compile-time error for a class to attempt to extend or implement \code{i
nt}. It is a compile-time error for a class to attempt to extend or implement \c
ode{double}. It is a compile-time error for any type other than the types \code{
int} and \code{double} to attempt to extend or implement \code{num}. |
| 2623 |
| 2624 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}. |
| 2625 |
| 2626 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}. |
| 2627 The static type of a literal double is \code{double}. |
| 2628 |
| 2629 \subsection{Booleans} |
| 2630 \label{booleans} |
| 2631 |
| 2632 The reserved words \TRUE{} and \FALSE{} denote objects that represent the boolea
n values true and false respectively. They are the {\em boolean literals}. |
| 2633 |
| 2634 \begin{grammar} |
| 2635 {\bf booleanLiteral:}\TRUE{}; |
| 2636 \FALSE{} |
| 2637 . |
| 2638 \end{grammar} |
| 2639 |
| 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 or implement\code{ bool}. |
| 2641 |
| 2642 \commentary{ |
| 2643 It follows that the two boolean literals are the only two instances of \code{boo
l}. |
| 2644 } |
| 2645 |
| 2646 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}. |
| 2647 |
| 2648 \subsubsection{Boolean Conversion} |
| 2649 \label{booleanConversion} |
| 2650 |
| 2651 {\em Boolean conversion} maps any object $o$ into a boolean. Boolean conversion
is defined by the function |
| 2652 |
| 2653 \begin{dartCode} |
| 2654 (bool v)\{ |
| 2655 \ASSERT{}(v != \NULL{}); |
| 2656 % \IF{} (\NULL{} == v) \{ \THROW{} \NEW{} AssertionError('null is not a bo
ol')\}; |
| 2657 \RETURN{} identical(v, \TRUE{}); |
| 2658 \}(o) |
| 2659 \end{dartCode} |
| 2660 |
| 2661 \rationale{ |
| 2662 Boolean conversion is used as part of control-flow constructs and boolean expres
sions. Ideally, one would simply insist that control-flow decisions be based ex
clusively on booleans. This is straightforward in a statically typed setting. I
n a dynamically typed language, it requires a dynamic check. Sophisticated virtu
al machines can minimize the penalty involved. Alas, Dart must be compiled into
Javascript. Boolean conversion allows this to be done efficiently. |
| 2663 |
| 2664 At the same time, this formulation differs radically from Javascript, where most
numbers and objects are interpreted as \TRUE{}. Dart's approach prevents usage
s such \code{\IF{} (a-b) ... ; }because it does not agree with the low level con
ventions whereby non-null objects or non-zero numbers are treated as \TRUE{}. In
deed, there is no way to derive \TRUE{} from a non-boolean object via boolean co
nversion, so this kind of low level hackery is nipped in the bud. |
| 2665 |
| 2666 Dart also avoids the strange behaviors that can arise due to the interaction of
boolean conversion with autoboxing in Javascript. A notorious example is the sit
uation where \FALSE{} can be interpreted as \TRUE{}. In Javascript, booleans are
not objects, and instead are autoboxed into objects where ``needed''. If \FALS
E{} gets autoboxed into an object, that object can be coerced into \TRUE{} (as i
t is a non-null object). |
| 2667 } |
| 2668 |
| 2669 \commentary{Because boolean conversion requires its parameter to be a boolean, a
ny construct that makes use of boolean conversion will cause a dynamic type erro
r in checked mode if the value to be converted is not a boolean. |
| 2670 } |
| 2671 |
| 2672 \subsection{Strings} |
| 2673 \label{strings} |
| 2674 |
| 2675 A {\em string} is a sequence of UTF-16 code units. |
| 2676 |
| 2677 \rationale{ |
| 2678 This decision was made for compatibility with web browsers and Javascript. Earli
er versions of the specification required a string to be a sequence of valid Uni
code code points. Programmers should not depend on this distinction. |
| 2679 } |
| 2680 |
| 2681 \begin{grammar} |
| 2682 {\bf stringLiteral:}(multilineString $|$ singleLineString)+ |
| 2683 . |
| 2684 \end{grammar} |
| 2685 |
| 2686 A string can be either a sequence of single line strings or a multiline string. |
| 2687 |
| 2688 \begin{grammar} |
| 2689 {\bf singleLineString:}`{\escapegrammar \code{"}}' stringContentDQ* `{\escapegr
ammar \code{"}}'; |
| 2690 `{\escapegrammar \code{'}}' stringContentSQ* `{\escapegrammar \code{'}}'; |
| 2691 `r' `{\escapegrammar \code{'}}' (\~{}( `{\escapegrammar \code{'}}' $|$ NEW
LINE ))* `{\escapegrammar \code{'}}'; |
| 2692 `r' `{\escapegrammar \code{"}}' (\~{}( `{\escapegrammar \code{"}}' $|$ NEW
LINE ))* `{\escapegrammar \code{"}}' |
| 2693 . |
| 2694 \end{grammar} |
| 2695 |
| 2696 A single line string is delimited by either matching single quotes or matching d
ouble quotes. |
| 2697 |
| 2698 \commentary{ |
| 2699 Hence, `abc' and ``abc'' are both legal strings, as are `He said ``To be or not
to be'' did he not?' and ``He said `To be or not to be' didn't he''. However `
`This ` is not a valid string, nor is `this''. |
| 2700 } |
| 2701 |
| 2702 \commentary{The grammar ensures that a single line string cannot span more than
one line of source code, unless it includes an interpolated expression that span
s multiple lines. |
| 2703 } |
| 2704 |
| 2705 Adjacent |
| 2706 %single line |
| 2707 strings are implicitly concatenated to form a single string literal. |
| 2708 %, and so are adjacent multiline strings, but the two forms may not be mixed. |
| 2709 |
| 2710 |
| 2711 \commentary{Here is an example} |
| 2712 |
| 2713 \begin{dartCode} |
| 2714 print("A string" "and then another"); // prints: A stringand then another |
| 2715 \end{dartCode} |
| 2716 |
| 2717 \rationale{Dart also supports the operator + for string concatenation. |
| 2718 |
| 2719 The + operator on Strings requires a String argument. It does not coerce its arg
ument into a string. This helps avoid puzzlers such as |
| 2720 } |
| 2721 |
| 2722 \begin{dartCode} |
| 2723 print("A simple sum: 2 + 2 = " + |
| 2724 2 + 2); |
| 2725 \end{dartCode} |
| 2726 |
| 2727 \rationale{ which this prints 'A simple sum: 2 + 2 = 22' rather than 'A simple
sum: 2 + 2 = 4'. |
| 2728 However, the use the concatenation operation is still discouraged for efficienc
y reasons. Instead, the recommended Dart idiom is to use string interpolation. |
| 2729 } |
| 2730 |
| 2731 \begin{dartCode} |
| 2732 print("A simple sum: 2 + 2 = \$\{2+2\}"); |
| 2733 \end{dartCode} |
| 2734 |
| 2735 |
| 2736 \rationale{String interpolation work well for most cases. The main situation whe
re it is not fully satisfactory is for string literals that are too large to fit
on a line. Multiline strings can be useful, but in some cases, we want to visua
lly align the code. This can be expressed by writing smaller strings separated b
y whitespace, as shown here:} |
| 2737 |
| 2738 |
| 2739 |
| 2740 |
| 2741 \begin{dartCode} |
| 2742 'Imagine this is a very long string that does not fit on a line. What shall we d
o? ' |
| 2743 'Oh what shall we do? ' |
| 2744 'We shall split it into pieces ' |
| 2745 'like so'. |
| 2746 \end{dartCode} |
| 2747 |
| 2748 |
| 2749 |
| 2750 |
| 2751 |
| 2752 \begin{grammar} |
| 2753 {\bf multilineString:}`{\escapegrammar \texttt{"""}}' stringContentTDQ* `{\es
capegrammar \texttt{"""}}'; |
| 2754 `{\escapegrammar \code{'}\code{'}\code{'}}' stringContentTSQ* `{\escapegra
mmar \code{'}\code{'}\code{'}}'; |
| 2755 `r' `{\escapegrammar \texttt{"""}}' (\~{} `{\escapegrammar \texttt{"""}}'
)* `{\escapegrammar \texttt{"""}}'; |
| 2756 `r' `{\escapegrammar \code{'}\code{'}\code{'}}' (\~{} `{\escapegrammar \co
de{'}\code{'}\code{'}}')* `{\escapegrammar \code{'}\code{'}\code{'}}' |
| 2757 . |
| 2758 |
| 2759 |
| 2760 {\bf ESCAPE\_SEQUENCE:} `$\backslash$ n'; |
| 2761 `$\backslash$ r'; |
| 2762 `$\backslash$ f'; |
| 2763 `$\backslash$ b'; |
| 2764 `$\backslash$ t'; |
| 2765 `$\backslash$ v'; |
| 2766 `$\backslash$ x' HEX\_DIGIT HEX\_DIGIT; |
| 2767 `$\backslash$ u' HEX\_DIGIT HEX\_DIGIT HEX\_DIGIT HEX\_DIGIT; |
| 2768 `$\backslash$ u\{' HEX\_DIGIT\_SEQUENCE `\}' |
| 2769 . |
| 2770 |
| 2771 {\bf HEX\_DIGIT\_SEQUENCE:} |
| 2772 HEX\_DIGIT HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? HEX\_DIGIT? |
| 2773 . |
| 2774 |
| 2775 \end{grammar} |
| 2776 |
| 2777 Multiline strings are delimited by either matching triples of single quotes or m
atching triples of double quotes. If the first line of a multiline string consis
ts solely of the whitespace characters defined by the production {\em WHITESPACE
} \ref{lexicalRules}), possibly prefixed by $\backslash$, then that line is ign
ored, including the new line at its end. |
| 2778 |
| 2779 |
| 2780 \rationale{ |
| 2781 The idea is to ignore whitespace, where whitespace is defined as tabs, spaces a
nd newlines. These can be represented directly, but since for most characters pr
efixing by backslash is an identity, we allow those forms as well. |
| 2782 } |
| 2783 |
| 2784 Strings support escape sequences for special characters. The escapes are: |
| 2785 \begin{itemize} |
| 2786 \item $\backslash$n for newline, equivalent to $\backslash$x0A. |
| 2787 \item $\backslash$r for carriage return, equivalent to $\backslash$x0D. |
| 2788 \item $\backslash$f for form feed, equivalent to $\backslash$x0C. |
| 2789 \item $\backslash$b for backspace, equivalent to $\backslash$x08. |
| 2790 \item $\backslash$t for tab, equivalent to $\backslash$x09. |
| 2791 \item $\backslash$v for vertical tab, equivalent to $\backslash$x0B |
| 2792 \item $\backslash$x $HEX\_DIGIT_1$ $HEX\_DIGIT_2$, equivalent to $\backslash$u\{
$HEX\_DIGIT_1$ $HEX\_DIGIT_2$\}. |
| 2793 \item $\backslash$u $HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\_DIGIT_4$,
equivalent to $\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\
_DIGIT_4$\}. |
| 2794 \item $\backslash$u\{$HEX\_DIGIT\_SEQUENCE$\} is the unicode scalar value repres
ented by the $HEX\_DIGIT\_SEQUENCE$. It is a compile-time error if the value of
the $HEX\_DIGIT\_SEQUENCE$ is not a valid unicode scalar value. |
| 2795 \item \$ indicating the beginning of an interpolated expression. |
| 2796 \item Otherwise, $\backslash k$ indicates the character $k$ for any $k$ not in $
\{n, r, f, b, t, v, x, u\}$. |
| 2797 \end{itemize} |
| 2798 |
| 2799 Any string may be prefixed with the character `r', indicating that it is a {\em
raw string}, in which case no escapes or interpolations are recognized. |
| 2800 |
| 2801 It is a compile-time error if a non-raw string literal contains a character sequ
ence of the form $\backslash$x that is not followed by a sequence of two hexadec
imal digits. It is a compile-time error if a non-raw string literal contains a
character sequence of the form $\backslash$u that is not followed by either a se
quence of four hexadecimal digits, or by curly brace delimited sequence of hexad
ecimal digits. |
| 2802 |
| 2803 |
| 2804 |
| 2805 \begin{grammar} |
| 2806 {\bf stringContentDQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{"}}' $|
$ `\$' $|$ NEWLINE ); |
| 2807 `$\backslash$' \~{}( NEWLINE ); |
| 2808 stringInterpolation |
| 2809 . |
| 2810 |
| 2811 {\bf stringContentSQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{'}}' $|
$ `\$' $|$ NEWLINE ); |
| 2812 `$\backslash$' \~{}( NEWLINE ); |
| 2813 stringInterpolation |
| 2814 . |
| 2815 |
| 2816 |
| 2817 {\bf stringContentTDQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \texttt{"""}}
' $|$ `\$'); |
| 2818 stringInterpolation |
| 2819 . |
| 2820 |
| 2821 {\bf stringContentTSQ:}\~{}( `$\backslash$' $|$ `{\escapegrammar \code{'}\code{
'}\code{'}}' $|$ `\$'); |
| 2822 stringInterpolation |
| 2823 . |
| 2824 |
| 2825 {\bf NEWLINE:}$\backslash$ n; |
| 2826 $\backslash$ r |
| 2827 . |
| 2828 |
| 2829 \end{grammar} |
| 2830 |
| 2831 All string literals implement the built-in class \code{String}. It is a compile-
time error for a class to attempt to extend or implement \code{String}. Invoking
the getter \code{runtimeType} on a string literal returns the \code{Type} objec
t that is the value of the expression \code{String}. The static type of a string
literal is \code{String}. |
| 2832 |
| 2833 \subsubsection{String Interpolation} |
| 2834 \label{stringInterpolation} |
| 2835 |
| 2836 It is possible to embed expressions within non-raw string literals, such that th
e these expressions are evaluated, and the resulting values are converted into s
trings and concatenated with the enclosing string. This process is known as {\em
string interpolation}. |
| 2837 |
| 2838 \begin{grammar} |
| 2839 {\bf stringInterpolation:}`\$' IDENTIFIER\_NO\_DOLLAR; |
| 2840 `\$' `\{' expression `\}' % could be top level expression, no? |
| 2841 . |
| 2842 \end{grammar} |
| 2843 |
| 2844 \commentary{The reader will note that the expression inside the interpolation co
uld itself include strings, which could again be interpolated recursively. |
| 2845 } |
| 2846 |
| 2847 An unescaped \$ character in a string signifies the beginning of an interpolated
expression. The \$ sign may be followed by either: |
| 2848 \begin{itemize} |
| 2849 \item A single identifier $id$ that must not contain the \$ character. |
| 2850 \item An expression $e$ delimited by curly braces. |
| 2851 \end{itemize} |
| 2852 |
| 2853 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$''
}. |
| 2854 |
| 2855 \subsection{Symbols} |
| 2856 \label{symbols} |
| 2857 |
| 2858 A {\em symbol literal} denotes the name of a declaration in a Dart program. |
| 2859 |
| 2860 \begin{grammar} |
| 2861 {\bf symbolLiteral:} |
| 2862 `\#' (operator $|$ (identifier (`{\escapegrammar .}' identifier)*)) . |
| 2863 \end{grammar} |
| 2864 |
| 2865 A symbol literal \code{\#id} where \code{id} does not begin with an underscore (
Ô\code{\_}Õ) is equivalent to the expression \code{\CONST{} Symbol(ÔidÕ)}. |
| 2866 |
| 2867 A symbol literal \code{\#\_id} evaluates to the object that would be returned by
the call \code{mirror.getPrivateSymbol(ÔidÕ)} where mirror is an instance of th
e class \code{LibraryMirror} defined in the library \code{dart:mirrors}, reflect
ing the current library. |
| 2868 |
| 2869 \rationale{ |
| 2870 One may well ask what is the motivation for introducing literal symbols? In some
languages, symbols are canonicalized whereas strings are not. However literal s
trings are already canonicalized in Dart. Symbols are slightly easier to type c
ompared to strings and their use can become strangely addictive, but this is not
nearly sufficient justification for adding a literal form to the language. The
primary motivation is related to the use of reflection and a web specific practi
ce known as minification. |
| 2871 |
| 2872 Minification compresses identifiers consistently throughout a program in order t
o reduce download size. This practice poses difficulties for reflective program
s that refer to program declarations via strings. A string will refer to an iden
tifier in the source, but the identifier will no longer be used in the minified
code, and reflective code using these truing would fail. Therefore, Dart reflec
tion uses objects of type \code{Symbol} rather than strings. Instances of \code
{Symbol} are guaranteed to be stable with repeat to minification. Providing a li
teral form for symbols makes reflective code easier to read and write. The fact
that symbols are easy to type and can often act as convenient substitutes for en
ums are secondary benefits. |
| 2873 } |
| 2874 |
| 2875 The static type of a symbol literal is \code{Symbol}. |
| 2876 |
| 2877 \subsection{Lists} |
| 2878 \label{lists} |
| 2879 |
| 2880 A {\em list literal} denotes a list, which is an integer indexed collection of o
bjects. |
| 2881 |
| 2882 \begin{grammar} |
| 2883 {\bf listLiteral:} |
| 2884 \CONST{}? typeArguments? `[' (expressionList `,'?)? `]' |
| 2885 . |
| 2886 \end{grammar} |
| 2887 |
| 2888 A list may contain zero or more objects. The number of elements in a list is its
size. A list has an associated set of indices. An empty list has an empty set
of indices. A non-empty list has the index set $\{0 \ldots n -1\}$ where $n$ is
the size of the list. It is a runtime error to attempt to access a list using an
index that is not a member of its set of indices. |
| 2889 |
| 2890 |
| 2891 If a list literal begins with the reserved word \CONST{}, it is a {\em constant
list literal} which is a compile-time constant (\ref{constants}) and therefore e
valuated at compile-time. Otherwise, it is a {\em run-time list literal} and it
is evaluated at run-time. Only run-time list literals can be mutated |
| 2892 after they are created. Attempting to mutate a constant list literal will result
in a dynamic error. |
| 2893 |
| 2894 It is a compile-time error if an element of a constant list literal is not a com
pile-time constant. It is a compile-time error if the type argument of a constan
t list literal includes a type parameter. |
| 2895 \rationale{The binding of a type parameter is not known at compile-time, so we c
annot use type parameters inside compile-time constants.} |
| 2896 |
| 2897 The value of a constant list literal \CONST{} $<E>[e_1\ldots e_n]$ is an object
$a$ whose class implements the built-in class $List<E>$. The $i$th element of $
a$ is $v_{i+1}$, where $v_i$ is the value of the compile-time expression $e_i$.
The value of a constant list literal \CONST{} $[e_1 \ldots e_n]$ is defined as
the value of the constant list literal \CONST{}$ < \DYNAMIC{}>[e_1\ldots e_n]$. |
| 2898 |
| 2899 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$)}. |
| 2900 |
| 2901 \commentary{In other words, constant list literals are canonicalized.} |
| 2902 |
| 2903 A run-time list literal $<E>[e_1 \ldots e_n]$ is evaluated as follows: |
| 2904 \begin{itemize} |
| 2905 \item |
| 2906 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$. |
| 2907 \item |
| 2908 A fresh instance (\ref{generativeConstructors}) $a$, of size $n$, whose class
implements the built-in class $List<E>$ is allocated. |
| 2909 \item |
| 2910 |
| 2911 The operator \code{[]=} is invoked on $a$ with first argument $i$ and second a
rgument |
| 2912 %The $i$th element of $a$ is set to |
| 2913 $o_{i+1}, 0 \le i < n$. |
| 2914 \item |
| 2915 The result of the evaluation is $a$. |
| 2916 \end{itemize} |
| 2917 |
| 2918 |
| 2919 \commentary{ |
| 2920 Note that this document does not specify an order in which the elements are set.
This allows for parallel assignments into the list if an implementation so desi
res. The order can only be observed in checked mode (and may not be relied upon
): if element $i$ is not a subtype of the element type of the list, a dynamic ty
pe error will occur when $a[i]$ is assigned $o_{i-1}$. |
| 2921 } |
| 2922 |
| 2923 A runtime list literal $[e_1 \ldots e_n]$ is evaluated as $< \DYNAMIC{}>[e_1\l
dots e_n]$. |
| 2924 |
| 2925 |
| 2926 \commentary{ |
| 2927 There is no restriction precluding nesting of list literals. It follows from the
rules above that |
| 2928 $<List<int>>[[1, 2, 3], [4, 5, 6]]$ is a list with type parameter $List<int>$, c
ontaining two lists with type parameter \DYNAMIC{}. |
| 2929 } |
| 2930 |
| 2931 The static type of a list literal of the form \CONST{}$ <E>[e_1\ldots e_n]$ or
the form $<E>[e_1 \ldots e_n]$ is $List<E>$. The static type a list literal of
the form \CONST{} $[e_1 \ldots e_n$] or the form $[e_1\ldots e_n$] is $List< \
DYNAMIC{}>$. |
| 2932 |
| 2933 \rationale{ |
| 2934 It is tempting to assume that the type of the list literal would be computed bas
ed on the types of its elements. However, for mutable lists this may be unwarran
ted. Even for constant lists, we found this behavior to be problematic. Since co
mpile-time is often actually runtime, the runtime system must be able to perform
a complex least upper bound computation to determine a reasonably precise type.
It is better to leave this task to a tool in the IDE. It is also much more unif
orm (and therefore predictable and understandable) to insist that whenever types
are unspecified they are assumed to be the unknown type \DYNAMIC{}. |
| 2935 } |
| 2936 |
| 2937 %Invoking the getter \code{runtimeType} on a list literal returns the \code{Type
} object that is the value of the expression \code{List}. The static type of a l
ist literal is \code{List}. |
| 2938 % what about generics? |
| 2939 |
| 2940 \subsection{Maps} |
| 2941 \label{maps} |
| 2942 |
| 2943 A {\em map literal} denotes a map object. |
| 2944 |
| 2945 \begin{grammar} |
| 2946 {\bf mapLiteral:} |
| 2947 \CONST{}? typeArguments? `\{' (mapLiteralEntry (`,' mapLiteralEntry)* `,'
?)? `\}' |
| 2948 . |
| 2949 |
| 2950 {\bf mapLiteralEntry:} |
| 2951 % identifier `{\escapegrammar :}' expression; |
| 2952 expression `{\escapegrammar :}' expression |
| 2953 . |
| 2954 \end{grammar} |
| 2955 |
| 2956 A {\em map literal} consists of zero or more entries. Each entry has a {\em key}
and a {\em value}. Each key and each value is denoted by an expression. |
| 2957 |
| 2958 If a map literal begins with the reserved word \CONST{}, it is a {\em constant m
ap literal} which is a compile-time constant (\ref{constants}) and therefore eva
luated at compile-time. Otherwise, it is a {\em run-time map literal} and it is
evaluated at run-time. Only run-time map literals can be mutated |
| 2959 after they are created. Attempting to mutate a constant map literal will result
in a dynamic error. |
| 2960 |
| 2961 It is a compile-time error if either a key or a value of an entry in a constant
map literal is not a compile-time constant. It is a compile-time error if the ke
y of an entry in a constant map literal is an instance of a class that implement
s the operator $==$ unless the key is a string or integer. It is a compile-time
error if the type arguments of a constant map literal include a type parameter. |
| 2962 |
| 2963 The value of a constant map literal \CONST{}$ <K, V>\{k_1:e_1\ldots k_n :e_n\}$
is an object $m$ whose class implements the built-in class $Map<K, V>$. The ent
ries of $m$ are $u_i:v_i, i \in 1 .. n$, where $u_i$ is the value of the compile
-time expression $k_i$ and $v_i$ is the value of the compile-time expression $e_
i$. The value of a constant map literal \CONST{} $\{k_1:e_1\ldots k_n :e_n\}$
is defined as the value of a constant map literal \CONST{} $<\DYNAMIC{}, \DYNAMI
C{}>\{k_1:e_1\ldots k_n :e_n\}$. |
| 2964 |
| 2965 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$)}. |
| 2966 |
| 2967 \commentary{In other words, constant map literals are canonicalized.} |
| 2968 |
| 2969 A runtime map literal $<K, V>\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as follow
s: |
| 2970 \begin{itemize} |
| 2971 \item |
| 2972 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$. |
| 2973 \item |
| 2974 A fresh instance (\ref{generativeConstructors}) $m$ whose class implements the b
uilt-in class $Map<K, V>$ is allocated. |
| 2975 \item |
| 2976 The operator \code{[]=} is invoked on $m$ with first argument $u_i$ and second
argument $o_i, i \in 1.. n$. |
| 2977 \item |
| 2978 The result of the evaluation is $m$. |
| 2979 \end{itemize} |
| 2980 |
| 2981 |
| 2982 A runtime map literal $\{k_1:e_1\ldots k_n :e_n\}$ is evaluated as $<\DYNAMIC{
}, \DYNAMIC{}>\{k_1:e_1\ldots k_n :e_n\}$. |
| 2983 |
| 2984 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. |
| 2985 |
| 2986 A map literal is ordered: iterating over the keys and/or values of the maps alwa
ys happens in the |
| 2987 order the keys appeared in the source code. |
| 2988 |
| 2989 \commentary{ |
| 2990 Of course, if a key repeats, the order is defined by first occurrence, but the v
alue is defined by the last. |
| 2991 } |
| 2992 |
| 2993 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{}>$. |
| 2994 |
| 2995 |
| 2996 \subsection{Throw} |
| 2997 \label{throw} |
| 2998 |
| 2999 The {\em throw expression} is used to raise an exception. |
| 3000 |
| 3001 \begin{grammar} |
| 3002 {\bf throwExpression:} |
| 3003 \THROW{} expression |
| 3004 . |
| 3005 |
| 3006 {\bf throwExpressionWithoutCascade:} |
| 3007 \THROW{} expressionWithoutCascade |
| 3008 . |
| 3009 |
| 3010 \end{grammar} |
| 3011 |
| 3012 The {\em current exception} is the last unhandled exception thrown. |
| 3013 |
| 3014 Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as
follows: |
| 3015 |
| 3016 The expression $e$ is evaluated yielding a value $v$. If $v$ evaluates to \NULL{
}, then a \code{NullThrownError} is thrown. Otherwise, control is transferred to
the nearest dynamically enclosing exception handler (\ref{try}), with the curre
nt exception set to $v$. |
| 3017 |
| 3018 \commentary{ |
| 3019 There is no requirement that the expression $e$ evaluate to a special kind of ex
ception or error object. |
| 3020 } |
| 3021 |
| 3022 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 the object was first thrown. |
| 3023 |
| 3024 The static type of a throw expression is $\bot$. |
| 3025 |
| 3026 |
| 3027 \subsection{ Function Expressions} |
| 3028 \label{functionExpressions} |
| 3029 |
| 3030 A {\em function literal} is an object that encapsulates an executable unit of co
de. |
| 3031 |
| 3032 \begin{grammar} |
| 3033 {\bf functionExpression:} |
| 3034 formalParameterList functionExpressionBody |
| 3035 . |
| 3036 |
| 3037 |
| 3038 {\bf functionExpressionBody:} |
| 3039 `={\escapegrammar \gt}' expression; |
| 3040 block |
| 3041 . |
| 3042 \end{grammar} |
| 3043 |
| 3044 The class of a function literal implements the built-in class \code{Function}.
|
| 3045 %Invoking the getter \code{runtimeType} on a function literal returns the \code{
Type} object that is the value of the expression \code{Function}. |
| 3046 % not necessarily |
| 3047 |
| 3048 |
| 3049 %Q{Can anyone implement it? Then we should define things via call} |
| 3050 |
| 3051 The static type of a function literal of the form $(T_1$ $a_1, \ldots, T_n$ $a_n
, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k]) => e$ is $(T_1 \l
dots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarrow T_0$, whe
re $T_0$ is the static type of $e$. In any case where $T_i, 1 \le i \le n+k$, is
not specified, it is considered to have been specified as \DYNAMIC{}. |
| 3052 |
| 3053 The static type of a function literal of the form $(T_1$ $a_1, \ldots, T_n$ $a_n
, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\}) => e$ is $(T_1
\ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow T_0$,
where $T_0$ is the static type of $e$. In any case where $T_i, 1 \le i \le n+k$
, is not specified, it is considered to have been specified as \DYNAMIC{}. |
| 3054 |
| 3055 The static type of a function literal of the form $(T_1$ $a_1, \ldots, T_n$ $a_
n, [T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k}= d_k])\{s\}$ is $(T_1 \l
dots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarrow \DYNAMIC
{}$. In any case where $T_i, 1 \le i \le n+k$, is not specified, it is considere
d to have been specified as \DYNAMIC{}. |
| 3056 |
| 3057 The static type of a function literal of the form $(T_1$ $a_1, \ldots, T_n$ $a_
n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})\{s\}$ is $(T_1
\ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow \DY
NAMIC{}$. In any case where $T_i, 1 \le i \le n+k$, is not specified, it is cons
idered to have been specified as \DYNAMIC{}. |
| 3058 |
| 3059 %** Now that declared return types are precluded, do we need some better return
type rule for (x){s} and friends? |
| 3060 |
| 3061 |
| 3062 |
| 3063 \subsection{ This} |
| 3064 \label{this} |
| 3065 |
| 3066 The reserved word \THIS{} denotes the target of the current instance member invo
cation. |
| 3067 |
| 3068 \begin{grammar} |
| 3069 {\bf thisExpression:} |
| 3070 \THIS{} |
| 3071 . |
| 3072 \end{grammar} |
| 3073 |
| 3074 The static type of \THIS{} is the interface of the immediately enclosing class. |
| 3075 |
| 3076 \commentary{ |
| 3077 We do not support self-types at this point. |
| 3078 } |
| 3079 |
| 3080 It is a compile-time error if \THIS{} appears in a top-level function or variabl
e initializer, in a factory constructor, or in a static method or variable init
ializer, or in the initializer of an instance variable. |
| 3081 |
| 3082 \subsection{ Instance Creation} |
| 3083 \label{instanceCreation} |
| 3084 |
| 3085 Instance creation expressions invoke constructors to produce instances. |
| 3086 |
| 3087 %It is a compile-time error if any of the type arguments to a constructor of a g
eneric type invoked by a new expression or a constant object expression do not d
enote types in the enclosing lexical scope. |
| 3088 |
| 3089 %It is a compile-time error if a constructor of a non-generic type invoked by a
new expression or a constant object expression is passed any type arguments. It
is a compile-time error if a constructor of a generic type with $n$ type paramet
ers invoked by a new expression or a constant object expression is passed $m$ ty
pe arguments where $m \ne n$, or if any of its type arguments is misconstructed
(\ref{parameterizedTypes}). |
| 3090 |
| 3091 It is a static type warning if |
| 3092 the type $T$ in an instance creation expression of one of the forms |
| 3093 |
| 3094 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
| 3095 |
| 3096 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
| 3097 |
| 3098 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$,
|
| 3099 |
| 3100 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is
malformed (\ref{dynamicTypeSystem}) or malbounded (\ref{parameterizedTypes}). |
| 3101 %any of the type arguments to a constructor of a generic type $G$ invoked by a n
ew expression or a constant object expression are not subtypes of the bounds of
the corresponding formal type parameters of $G$. |
| 3102 |
| 3103 |
| 3104 \subsubsection{ New} |
| 3105 \label{new} |
| 3106 |
| 3107 The {\em new expression} invokes a constructor (\ref{constructors}). |
| 3108 |
| 3109 \begin{grammar} |
| 3110 {\bf newExpression:} |
| 3111 \NEW{} type (`{\escapegrammar .}' identifier)? arguments |
| 3112 . |
| 3113 \end{grammar} |
| 3114 |
| 3115 Let $e$ be a new expression of the form |
| 3116 |
| 3117 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ or
the form |
| 3118 |
| 3119 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
| 3120 |
| 3121 %It is a runtime type error if |
| 3122 %the type $T$ is malformed. |
| 3123 %It is a static warning if $T$ is a malformed type. |
| 3124 |
| 3125 %not a class accessible in the current scope, optionally followed by type argum
ents. |
| 3126 |
| 3127 If $T$ is a class or parameterized type accessible in the current scope then: |
| 3128 \begin{itemize} |
| 3129 \item |
| 3130 If $e$ is of the form \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots ,
x_{n+k}: a_{n+k})$ it is a static warning if $T.id$ is not the name of a constr
uctor declared by the type $T$. If $e$ is of the form \NEW{} $T(a_1, \ldots , a
_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a static warning if the
type $T$ does not declare a constructor with the same name as the declaration of
$T$. |
| 3131 \end{itemize} |
| 3132 |
| 3133 If $T$ is a parameterized type (\ref{parameterizedTypes}) $S<U_1, \ldots, U_m>$
, let $R = S$. |
| 3134 %It is a |
| 3135 %compile-time CHANGED |
| 3136 %runtime type |
| 3137 %error if $S$ is not a generic (\ref{generics}) type with $m$ type parameters. |
| 3138 If $T$ is not a parameterized type, let $R = T$. |
| 3139 Furthermore, if $e$ is of the form \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n
+1}, \ldots , x_{n+k}: a_{n+k})$ then let $q$ be the constructor $T.id$, other
wise let $q$ be the constructor $T$. |
| 3140 |
| 3141 If $R$ is a generic with $l = m$ type parameters then |
| 3142 \begin{itemize} |
| 3143 \item $T$ is not a parameterized type, then for $ i \in 1 .. l$, let $V_i = \D
YNAMIC{}$. |
| 3144 \item If $T$ is a parameterized type then let $V_i = U_i$ for $ i \in 1 .. m$.
|
| 3145 \end{itemize} |
| 3146 |
| 3147 If $R$ is a generic with $l \ne m$ type parameters then for $ i \in 1 .. l$, let
$V_i = \DYNAMIC{}$. In any other case, let $V_i = U_i$ for $ i \in 1 .. m$. |
| 3148 |
| 3149 Evaluation of $e$ proceeds as follows: |
| 3150 |
| 3151 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}
: a_{n+k})$ is evaluated. |
| 3152 |
| 3153 Then, if $q$ is a non-factory constructor of an abstract class then an \code{Abs
tractClassInstantiationError} is thrown. |
| 3154 |
| 3155 If $T$ is malformed a dynamic error occurs. In checked mode, if $T$ is malbound
ed a dynamic error occurs. |
| 3156 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. |
| 3157 |
| 3158 Otherwise, if $q$ is a generative constructor (\ref{generativeConstructors}), th
en: |
| 3159 |
| 3160 %Let $T_i$ be the type parameters of $R$ (if any) and let $B_i$ be the bound of
$T_i, 1 \le i \le l$. |
| 3161 %In checked mode, it is a dynamic type error if $V_i$ is not a subtype of $[V_
1, \ldots, V_l/T_1, \ldots, T_l]B_i, i \in 1.. l$. |
| 3162 |
| 3163 \commentary{Note that it this point we are assured that the number of actual typ
e arguments match the number of formal type parameters.} |
| 3164 |
| 3165 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 to an object $o_f$ and
$f$ is bound to $o_f$. Otherwise $f$ is bound to \NULL{}. |
| 3166 |
| 3167 \commentary{ |
| 3168 Observe that \THIS{} is not in scope in $e_f$. Hence, the initialization cannot
depend on other properties of the object being instantiated. |
| 3169 } |
| 3170 |
| 3171 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$. |
| 3172 |
| 3173 Otherwise, $q$ is a factory constructor (\ref{factories}). Then: |
| 3174 |
| 3175 %Let $T_i$ be the type parameters of $R$ (if any) and let $B_i$ be the bound of
$T_i, 1 \le i \le l$. |
| 3176 %In checked mode, it is a dynamic type error if $V_i$ is not a subtype of $[V_
1, \ldots, V_l/T_1, \ldots, T_l]B_i, i \in 1.. l$. |
| 3177 |
| 3178 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 $[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}))$}. |
| 3179 |
| 3180 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$. |
| 3181 |
| 3182 It is a static warning if $q$ is a constructor of an abstract class and $q$ is n
ot a factory constructor. |
| 3183 |
| 3184 \commentary{The above gives precise meaning to the idea that instantiating an ab
stract class leads to a warning. |
| 3185 A similar clause applies to constant object creation in the next section. |
| 3186 } |
| 3187 |
| 3188 \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. |
| 3189 } |
| 3190 |
| 3191 The static type of an instance creation expression of either the form |
| 3192 |
| 3193 \NEW{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
| 3194 |
| 3195 or the form |
| 3196 |
| 3197 \NEW{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
| 3198 |
| 3199 is $T$. |
| 3200 It is a static warning if the static type of $a_i, 1 \le i \le n+ k$ may not be
assigned to the type of the corresponding formal parameter of the constructor $T
.id$ (respectively $T$). |
| 3201 |
| 3202 |
| 3203 |
| 3204 \subsubsection{ Const} |
| 3205 \label{const} |
| 3206 |
| 3207 A {\em constant object expression} invokes a constant constructor (\ref{constant
Constructors}). |
| 3208 |
| 3209 \begin{grammar} |
| 3210 {\bf constObjectExpression:} |
| 3211 \CONST{} type ('{\escapegrammar .}' identifier)? arguments |
| 3212 . |
| 3213 \end{grammar} |
| 3214 |
| 3215 Let $e$ be a constant object expression of the form \CONST{} $T.id(a_1, \ldots
, a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ or the form \CONST{} $T(a_
1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. It is a compile-
time error if $T$ is not a class accessible in the current scope. It is a compi
le-time error if $T$ is a parameterized type. |
| 3216 |
| 3217 If $e$ is of the form \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots
, x_{n+k}: a_{n+k})$ it is a compile-time error if $T.id$ is not the name of a
constant constructor declared by the type $T$. If $e$ is of the form \CONST{} $
T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ it is a compi
le-time error if the type $T$ does not declare a constant constructor with the s
ame name as the declaration of $T$. |
| 3218 |
| 3219 In all of the above cases, it is a compile-time error if $a_i, i\in 1 .. n + k$
, is not a compile-time constant expression. |
| 3220 |
| 3221 %If $T$ is a parameterized type (\ref{parameterizedTypes}) $S<U_1, \ldots, U_m>
$, let $R = S$. It is a compile-time error if $T$ is is malformed. If $T$ is no
t a parameterized type, let $R = T$. |
| 3222 %Finally, |
| 3223 % If $T$ is a generic with $l$ retype parameters, then for all $ i \in 1 .. l$,
let $V_i = \DYNAMIC{}$. |
| 3224 |
| 3225 Evaluation of $e$ proceeds as follows: |
| 3226 |
| 3227 First, if $e$ is of the form \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1},
\ldots , x_{n+k}: a_{n+k})$ then let $i$ be the value of the expression \NEW{}
$T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. Otherwis
e, $e$ must be of the form |
| 3228 |
| 3229 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
| 3230 |
| 3231 in which case let $i$ be the result of evaluating \NEW{} $T(a_1, \ldots , a_n, x
_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. Then: |
| 3232 \begin{itemize} |
| 3233 \item If during execution of the program, a constant object expression has alrea
dy evaluated to an instance $j$ of class $R$ with type arguments $V_i, 1 \le i \
le m$, then: |
| 3234 \begin{itemize} |
| 3235 \item For each instance variable $f$ of $i$, let $v_{if}$ be the value of the fi
eld $f$ in $i$, and let $v_{jf}$ be the value of the field $f$ in $j$. If \code
{identical($v_{if}$, $v_{jf}$)} for all fields $f$ in $i$, then the value of $e$
is $j$, otherwise the value of $e$ is $i$. |
| 3236 \end{itemize} |
| 3237 \item Otherwise the value of $e$ is $i$. |
| 3238 \end{itemize} |
| 3239 |
| 3240 \commentary{ |
| 3241 In other words, constant objects are canonicalized. In order to determine if an
object is actually new, one has to compute it; then it can be compared to any c
ached instances. If an equivalent object exists in the cache, we throw away the
newly created object and use the cached one. Objects are equivalent if they have
identical fields and identical type arguments. Since the constructor cannot ind
uce any side effects, the execution of the constructor is unobservable. The con
structor need only be executed once per call site, at compile-time. |
| 3242 } |
| 3243 |
| 3244 The static type of a constant object expression of either the form |
| 3245 |
| 3246 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
| 3247 |
| 3248 or the form |
| 3249 |
| 3250 \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
| 3251 |
| 3252 is $T$. It is a static warning if the static type of $a_i, 1 \le i \le n+ k$ may
not be assigned to the type of the corresponding formal parameter of the constr
uctor $T.id$ (respectively $T$). |
| 3253 |
| 3254 It is a compile-time error if evaluation of a constant object results in an unca
ught exception being thrown. |
| 3255 |
| 3256 \commentary{ |
| 3257 To see how such situations might arise, consider the following examples: |
| 3258 } |
| 3259 |
| 3260 \begin{dartCode} |
| 3261 \CLASS{} A \{ |
| 3262 \FINAL{} x; |
| 3263 \CONST{} A(p): x = p * 10; |
| 3264 \} |
| 3265 |
| 3266 \CONST{} A("x"); // compile-time error |
| 3267 \CONST{} A(5); // legal |
| 3268 |
| 3269 |
| 3270 \CLASS{} IntPair \{ |
| 3271 \CONST{} IntPair(\THIS{}.x, \THIS{}.y); |
| 3272 \FINAL{} int x; |
| 3273 \FINAL{} int y; |
| 3274 \OPERATOR *(v) $=>$ \NEW{} IntPair(x*v, y*v); |
| 3275 \} |
| 3276 |
| 3277 \CONST{} A(\CONST{} IntPair(1,2)); // compile-time error: illegal in a subtler w
ay |
| 3278 \end{dartCode} |
| 3279 |
| 3280 \commentary{ |
| 3281 Due to the rules governing constant constructors, evaluating the constructor \co
de{A()} with the argument \code{''x''} or the argument \code{\CONST{} IntPair(1,
2)} would cause it to throw an exception, resulting in a compile-time error. |
| 3282 } |
| 3283 |
| 3284 |
| 3285 Given an instance creation expression of the form \CONST{} $q(a_1, \ldots , a_n)
$ it is a static warning if $q$ is a constructor of an abstract class (\ref{abs
tractInstanceMembers}) but $q$ is not a factory constructor. |
| 3286 |
| 3287 |
| 3288 \subsection{ Spawning an Isolate} |
| 3289 \label{spawningAnIsolate} |
| 3290 |
| 3291 Spawning an isolate is accomplished via what is syntactically an ordinary librar
y call, invoking one of the functions \code{spawnUri()} or \code{spawnFunction()
}defined in the \code{dart:isolate} library. However, such calls have the sema
ntic effect of creating a new isolate with its own memory and thread of control. |
| 3292 |
| 3293 An isolate's memory is finite, as is the space available to its thread's call st
ack. It is possible for a running isolate to exhaust its memory or stack, result
ing in a run-time error that cannot be effectively caught, which will force the
isolate to be suspended. |
| 3294 |
| 3295 \commentary{ |
| 3296 As discussed in section \ref{errorsAndWarnings}, the handling of a suspended iso
late is the responsibility of the embedder. |
| 3297 } |
| 3298 |
| 3299 \subsection{ Property Extraction} |
| 3300 \label{propertyExtraction} |
| 3301 |
| 3302 {\em Property extraction} allows for a member of an object to be concisely extra
cted from the object. |
| 3303 If $e$ is an expression that evaluates to an object $o$, and if $m$ is the name
of a concrete method member of $e$, then $e.m$ is defined to be equivalent to: |
| 3304 |
| 3305 \begin{itemize} |
| 3306 %\item $(r_1, \ldots, r_n)\{\RETURN{}$ $o.m(r_1, \ldots, r_n);\}$ if $m$ has on
ly required parameters $r_1, \ldots r_n$. |
| 3307 %\item $(r_1, \ldots, r_n, rest)\{return$ $o.m(r_1, \ldots, r_n, rest);\}$ if $
m$ has required parameters $r_1, \ldots r_n$, and a rest parameter $rest$. |
| 3308 %\item |
| 3309 |
| 3310 % so the issue is that o is not an expression, but we don't want to bind to e, a
s its evaluation |
| 3311 % could have side effects, result in different objects at different times etc. |
| 3312 % so we use u, where u is a fresh final variable bound to o |
| 3313 % |
| 3314 \item $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})\{$\RETURN{} $u.m(r
_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);\}$ if $m$ has required parameters
$r_1, \ldots, r_n$, and named parameters $p_1, \ldots, p_k$ with defaults $d_1,
\ldots, d_k$. |
| 3315 \item $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])\{$\RETURN{} $u.m(r_1,
\ldots, r_n, p_1, \ldots, p_k);\}$ if $m$ has required parameters $r_1, \ldots,
r_n$, and optional positional parameters $p_1, \ldots, p_k$ with defaults $d_1,
\ldots, d_k$. |
| 3316 \end{itemize} |
| 3317 |
| 3318 where $u$ is a fresh final variable bound to $o$, except that: |
| 3319 \begin{enumerate} |
| 3320 \item iff \code{identical($o_1, o_2$)} then \cd{$o_1.m$ == $o_2.m$}. |
| 3321 \item The static type of the property extraction is the static type of function
$T.m$, where $T$ is the static type of $e$, if $T.m$ is defined. Otherwise the s
tatic type of $e.m$ is \DYNAMIC{}. |
| 3322 \end{enumerate} |
| 3323 |
| 3324 \commentary{ |
| 3325 There is no guarantee that \cd{identical($o_1.m, o_2.m$)}. Dart implementations
are not required to canonicalize these or any other closures. |
| 3326 } |
| 3327 % local functions that have a closure extracted are always different |
| 3328 |
| 3329 \rationale{ |
| 3330 The special treatment of equality in this case facilitates the use of extracted
property functions in APIs where callbacks such as event listeners must often be
registered and later unregistered. A common example is the DOM API in web brows
ers. |
| 3331 } |
| 3332 |
| 3333 Otherwise |
| 3334 %, if $m$ is the name of a getter (\ref{getters}) member of $e$ (declared implic
itly or explicitly) then |
| 3335 $e.m$ is treated as a getter invocation (\ref{getterInvocation})). |
| 3336 |
| 3337 |
| 3338 \commentary{Observations: |
| 3339 \begin{enumerate} |
| 3340 \item One cannot extract a getter or a setter. |
| 3341 \item One can tell whether one implemented a property via a method or via field/
getter, which means that one has to plan ahead as to what construct to use, and
that choice is reflected in the interface of the class. |
| 3342 \end{enumerate} |
| 3343 } |
| 3344 |
| 3345 Let $S$ be the superclass of the immediately enclosing class. If $m$ is the name
of a concrete method member of $S$, then the expression $\SUPER{}.m$ is define
d to be equivalent to: |
| 3346 |
| 3347 \begin{itemize} |
| 3348 %\item $(r_1, \ldots, r_n)\{\RETURN{}$ $o.m(r_1, \ldots, r_n);\}$ if $m$ has on
ly required parameters $r_1, \ldots r_n$. |
| 3349 %\item $(r_1, \ldots, r_n, rest)\{return$ $o.m(r_1, \ldots, r_n, rest);\}$ if $
m$ has required parameters $r_1, \ldots r_n$, and a rest parameter $rest$. |
| 3350 %\item |
| 3351 \item $(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})\{$\RETURN{} $\SUPE
R{}.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);\}$ if $m$ has required para
meters $r_1, \ldots, r_n$, and named parameters $p_1, \ldots, p_k$ with defaults
$d_1, \ldots, d_k$. |
| 3352 \item $(r_1, \ldots, r_n, [p_1 = d_1, \ldots , p_k = d_k])\{$\RETURN{} $\SUPER{}
.m(r_1, \ldots, r_n, p_1, \ldots, p_k);\}$ if $m$ has required parameters $r_1,
\ldots, r_n$, and optional positional parameters $p_1, \ldots, p_k$ with default
s $d_1, \ldots, d_k$. |
| 3353 \end{itemize} |
| 3354 |
| 3355 Except that: |
| 3356 \begin{enumerate} |
| 3357 \item iff \code{identical($o_1, o_2$)} then \cd{$o_1.m$ == $o_2.m$}. |
| 3358 \item |
| 3359 The static type of the property extraction is the static type of the method $S.m
$, if $S.m$ is defined. Otherwise the static type of $\SUPER{}.m$ is \DYNAMIC{}
. |
| 3360 \end{enumerate} |
| 3361 |
| 3362 Otherwise |
| 3363 %, if $m$ is the name of a getter (\ref{getters}) member of $S$ (declared implic
itly or explicitly) then |
| 3364 $\SUPER{}.m$ is treated as a getter invocation (\ref{getterInvocation})). |
| 3365 |
| 3366 \subsection{ Function Invocation} |
| 3367 \label{functionInvocation} |
| 3368 |
| 3369 Function invocation occurs in the following cases: when a function expression (
\ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), when
a method (\ref{methodInvocation}), getter (\ref{getterInvocation}) or setter (\
ref{assignment}) is invoked or when a constructor is invoked (either via instanc
e creation (\ref{instanceCreation}), constructor redirection (\ref{redirectingCo
nstructors}) or super initialization). The various kinds of function invocation
differ as to how the function to be invoked, $f$, is determined, as well as whe
ther \THIS{} is bound. Once $f$ has been determined, the formal parameters of $f
$ are bound to corresponding actual arguments. The body of $f$ is then executed
with the aforementioned bindings. Execution of the body terminates when the firs
t of the following occurs: |
| 3370 \begin{itemize} |
| 3371 \item An uncaught exception is thrown. |
| 3372 \item A return statement (\ref{return}) immediately nested in the body of $f$ is
executed. |
| 3373 \item The last statement of the body completes execution. |
| 3374 \end{itemize} |
| 3375 |
| 3376 |
| 3377 |
| 3378 |
| 3379 \subsubsection{ Actual Argument List Evaluation} |
| 3380 \label{actualArguments} |
| 3381 |
| 3382 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. |
| 3383 |
| 3384 \begin{grammar} |
| 3385 {\bf arguments:} |
| 3386 `(' argumentList? `)' |
| 3387 . |
| 3388 |
| 3389 {\bf argumentList:}namedArgument (`,' namedArgument)*; |
| 3390 % expressionList ',' spreadArgument; |
| 3391 expressionList (`,' namedArgument)* |
| 3392 % spreadArgument |
| 3393 . |
| 3394 |
| 3395 {\bf namedArgument:} |
| 3396 label expression % could be top level expression? |
| 3397 . |
| 3398 |
| 3399 %spreadArgument: |
| 3400 % '...' expression |
| 3401 % . |
| 3402 \end{grammar} |
| 3403 |
| 3404 Evaluation of an actual argument list of the form $(a_1, \ldots, a_m, q_1: a_{m+
1}, \ldots, q_l: a_{m+l})$ proceeds as follows: |
| 3405 |
| 3406 %Furthermore, if $p_k$ is a rest parameter, then one of the following cases hold
s: |
| 3407 %\begin{enumerate} |
| 3408 %\item $m = k-1$. Then $p_k$ is bound to a freshly allocated empty list. \Q{cant
we share it? identity?} |
| 3409 %\item $m = k$, and $a_k$ is a spread argument ...$e_k$. Then $p_k$ is bound to
the value of $e_k$. In checked mode, it is a dynamic type error if the type of
$p_k$ is not a supertype of the value of $e_k$. |
| 3410 %\item $m \ge k$. A freshly allocated list $r$ of the type of $p_k$ with size $
m - k + 1$ is allocated. and initialized such that $r_j = a_{k+j}, 0 \le j \le m
- k$. Then $p_k$ is bound to $r$. |
| 3411 %\end{enumerate} |
| 3412 |
| 3413 %Otherwise, i |
| 3414 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}$. |
| 3415 |
| 3416 \commentary{Simply stated, an argument list consisting of $m$ positional argumen
ts and $l$ named arguments is evaluated from left to right. |
| 3417 } |
| 3418 |
| 3419 |
| 3420 \subsubsection{ Binding Actuals to Formals} |
| 3421 \label{bindingActualsToFormals} |
| 3422 |
| 3423 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$. |
| 3424 |
| 3425 An evaluated actual argument list $o_1 \ldots o_{m+l}$ derived from an actual ar
gument list of the form $(a_1, \ldots, a_m, q_1: a_{m+1}, \ldots, q_l: a_{m+l})$
is bound to the formal parameters of $f$ as follows: |
| 3426 |
| 3427 \commentary{ |
| 3428 We have an argument list consisting of $m$ positional arguments and $l$ named ar
guments. We have a function with $h$ required parameters and $k$ optional parame
ters. The number of positional arguments must be at least as large as the number
of required parameters, and no larger than the number of positional parameters.
All named arguments must have a corresponding named parameter. You may not prov
ide a given named argument more than once. If an optional parameter has no corr
esponding argument, it gets its default value. In checked mode, all arguments mu
st belong to subtypes of the type of their corresponding formal. |
| 3429 } |
| 3430 |
| 3431 \commentary{ |
| 3432 If $l > 0$, then it is necessarily the case that $n = h$, because a method canno
t have both optional positional parameters and named parameters. |
| 3433 } |
| 3434 |
| 3435 |
| 3436 If $m < h$, or $m > n$, a \cd{NoSuchMethodError} is thrown. Furthermore, each $
q_i, 1 \le i \le l$, must have a corresponding named parameter in the set $\{p_
{n+1}, \ldots, p_{n +k}\}$ or a \cd{NoSuchMethodError} is thrown. Then $p_i$ is
bound to $o_i, i \in 1.. m$, and $q_j$ is bound to $o_{m+j}, j \in 1.. l$. All
remaining formal parameters of $f$ are bound to their default values. |
| 3437 |
| 3438 \commentary{All of these remaining parameters are necessarily optional and thus
have default values.} |
| 3439 |
| 3440 In checked mode, it is a dynamic type error if $o_i$ is not \NULL{} and the act
ual type (\ref{actualTypeOfADeclaration}) of $p_i$ is not a supertype of the ty
pe of $o_i, i \in 1.. m$. In checked mode, it is a dynamic type error if $o_{m+
j}$ is not \NULL{} and the actual type (\ref{actualTypeOfADeclaration}) of $q_j
$ is not a supertype of the type of $o_{m+j}, j \in 1.. l$. |
| 3441 |
| 3442 It is a compile-time error if $q_i = q_j$ for any $i \ne j$. |
| 3443 |
| 3444 Let $T_i$ be the static type of $a_i$, let $S_i$ be the type of $p_i, i \in 1 ..
h+k$ and let $S_q$ be the type of the named parameter $q$ of $f$. It is a stat
ic warning if $T_j$ may not be assigned to $S_j, j \in 1..m$. It is a static wa
rning if $m < h$ or if $m > n$. Furthermore, each $q_i, 1 \le i \le l$, must ha
ve a corresponding named parameter in the set $\{p_{n+1}, \ldots, p_{n +k}\}$ or
a static warning occurs. It is a static warning if $T_{m+j}$ may not be assign
ed to $S_{q_j}, j \in 1 .. l$. |
| 3445 |
| 3446 \subsubsection{ Unqualified Invocation} |
| 3447 \label{unqualifiedInvocation} |
| 3448 |
| 3449 An unqualified function invocation $i$ has the form |
| 3450 |
| 3451 $id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k})$, |
| 3452 |
| 3453 where $id$ is an identifier. |
| 3454 |
| 3455 If there exists a lexically visible declaration named $id$, let $f_{id}$ be the
innermost such declaration. Then: |
| 3456 \begin{itemize} |
| 3457 \item |
| 3458 If $f_{id}$ is a local function, a library function, a library or static getter
or a variable then $i$ is interpreted as a function expression invocation (\ref
{functionExpressionInvocation}). |
| 3459 \item |
| 3460 Otherwise, if $f_{id}$ is a static method of the enclosing class $C$, $i$ is equ
ivalent to $C.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})
$. |
| 3461 \item Otherwise, if $i$ occurs inside a top level or static function (be it func
tion, method, getter, or setter) or variable initializer, evaluation of $i$ cau
ses a \cd{NoSuchMethodError} to be thrown. |
| 3462 \end{itemize} |
| 3463 |
| 3464 %Otherwise, if there is an accessible (\ref{privacy}) static method named $id$ d
eclared in a superclass $S$ of the immediately enclosing class $C$ then i is equ
ivalent to the static method invocation $S.id(a_1, \ldots, a_n, x_{n+1}: a_{n+1}
, \ldots, x_{n+k}: a_{n+k})$. |
| 3465 |
| 3466 %\rationale{ |
| 3467 %Unqualified access to static methods of superclasses is inconsistent with the i
dea that static methods are not inherited. It is not particularly necessary and
may be restricted in future versions. |
| 3468 %} |
| 3469 |
| 3470 Otherwise, $i$ is equivalent to $\THIS{}.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1},
\ldots , x_{n+k}: a_{n+k})$. |
| 3471 |
| 3472 |
| 3473 |
| 3474 \subsubsection{ Function Expression Invocation} |
| 3475 \label{functionExpressionInvocation} |
| 3476 |
| 3477 A function expression invocation $i$ has the form |
| 3478 |
| 3479 $e_f(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$, |
| 3480 |
| 3481 where $e_f$ is an expression. If $e_f$ is an identifier $id$, then $id$ must nec
essarily denote a local function, a library function, a library or static getter
or a variable as described above, or $i$ is not considered a function expressio
n invocation. If $e_f$ is a property extraction expression (\ref{propertyExtract
ion}), then $i$ is is not a function expression invocation and is instead recogn
ized as an ordinary method invocation (\ref{ordinaryInvocation}). |
| 3482 |
| 3483 \commentary{ |
| 3484 \code{$a.b(x)$} is parsed as a method invocation of method \code{$b()$} on objec
t \code{$a$}, not as an invocation of getter \code{$b$} on \code{$a$} followed b
y a function call \code{$(a.b)(x)$}. If a method or getter \code{$b$} exists, t
he two will be equivalent. However, if \code{$b$} is not defined on \code{$a$},
the resulting invocation of \code{noSuchMethod()} would differ. The \code{Invoc
ation} passed to \code{noSuchMethod()} would describe a call to a method \code{$
b$} with argument \code{$x$} in the former case, and a call to a getter \code{$b
$} (with no arguments) in the latter. |
| 3485 } |
| 3486 |
| 3487 Otherwise: |
| 3488 |
| 3489 A function expression invocation $e_f(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldot
s , x_{n+k}: a_{n+k})$ is equivalent to $e_f.call(a_1, \ldots , a_n, x_{n+1}: a_
{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
| 3490 |
| 3491 \commentary{ |
| 3492 The implication of this definition, and the other definitions involving the meth
od \code{call()}, is that user defined types can be used as function values prov
ided they define a \code{call()} method. The method \code{call()} is special in
this regard. The signature of the \code{call()} method determines the signature
used when using the object via the built-in invocation syntax. |
| 3493 } |
| 3494 |
| 3495 It is a static warning if the static type $F$ of $e_f$ may not be assigned to a
function type. If $F$ is not a function type, the static type of $i$ is \DYNAMI
C{}. Otherwise |
| 3496 the static type of $i$ is the declared return type of $F$. |
| 3497 %\item Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static war
ning if $F$ is not a supertype of $(T_1, \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldot
s, T_{n+k}$ $x_{n+k}]) \to \bot$. |
| 3498 %\end{itemize} |
| 3499 |
| 3500 |
| 3501 \subsection{ Method Invocation} |
| 3502 \label{methodInvocation} |
| 3503 |
| 3504 Method invocation can take several forms as specified below. |
| 3505 |
| 3506 \subsubsection{Ordinary Invocation} |
| 3507 \label{ordinaryInvocation} |
| 3508 |
| 3509 An ordinary method invocation $i$ has the form |
| 3510 |
| 3511 $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ where $o$
is not the name of a class or a library prefix. |
| 3512 |
| 3513 Method invocation involves method lookup, defined next. |
| 3514 The result of a lookup of a method $m$ in object $o$ with respect to library $L$
is the result of a lookup of method $m$ in class $C$ with respect to library $
L$, where $C$ is the class of $o$. |
| 3515 |
| 3516 The result of a lookup of method $m$ in class $C$ with respect to library $L$ i
s: |
| 3517 If $C$ declares a concrete instance method named $m$ that is accessible to $L$,
then that method is the result of the lookup. Otherwise, if $C$ has a superclas
s $S$, then the result of the lookup is the result of looking up $m$ in $S$ wit
h respect to $L$. Otherwise, we say that the method lookup has failed. |
| 3518 |
| 3519 \rationale { |
| 3520 The motivation for skipping abstract members during lookup is largely to allow s
moother mixin composition. |
| 3521 } |
| 3522 |
| 3523 Evaluation of an ordinary method invocation $i$ of the form |
| 3524 |
| 3525 $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ |
| 3526 |
| 3527 proceeds as follows: |
| 3528 |
| 3529 First, the expression $o$ is evaluated to a value $v_o$. Next, 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 $f$ be the result
of looking up method $m$ in $v_o$ with respect to the current library $L$. |
| 3530 |
| 3531 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$. |
| 3532 |
| 3533 \commentary{ |
| 3534 We have an argument list consisting of $n$ positional arguments and $k$ named ar
guments. We have a function with $h$ required parameters and $l$ optional parame
ters. The number of positional arguments must be at least as large as the number
of required parameters, and no larger than the number of positional parameters.
All named arguments must have a corresponding named parameter. |
| 3535 } |
| 3536 |
| 3537 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. |
| 3538 |
| 3539 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 $v_o$. The value of $i$ is the value returned after $f$ is executed. |
| 3540 |
| 3541 If the method lookup has failed, then let $g$ be the result of looking up getter
(\ref{getterAndSetterLookup}) $m$ in $v_o$ with respect to $L$. If the getter l
ookup succeeded, let $v_g$ be the value of the getter invocation $o.m$. Then the
value of $i$ is the result of invoking |
| 3542 the static method \code{Function.apply()} with arguments $v.g, [o_1, \ldots , o_
n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$. |
| 3543 |
| 3544 If getter lookup has also failed, then a new instance $im$ of the predefined c
lass \code{Invocation} is created, such that : |
| 3545 \begin{itemize} |
| 3546 \item \code{im.isMethod} evaluates to \code{\TRUE{}}. |
| 3547 \item \code{im.memberName} evaluates to \code{'m'}. |
| 3548 \item \code{im.positionalArguments} evaluates to an immutable list with the same
values as \code{[$o_1, \ldots, o_n$]}. |
| 3549 \item \code{im.namedArguments} evaluates to an immutable map with the same keys
and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}. |
| 3550 \end{itemize} |
| 3551 |
| 3552 Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with argum
ent $im$, and the result of this invocation is the result of evaluating $i$. |
| 3553 |
| 3554 \commentary{Notice that the wording carefully avoids re-evaluating the receiver
$o$ and the arguments $a_i$. } |
| 3555 |
| 3556 Let $T$ be the static type of $o$. It is a static type warning if $T$ does not
have an accessible (\ref{privacy}) instance member named $m$. If $T.m$ exists
, it is a static type warning if the type $F$ of $T.m$ may not be assigned to a
function type. If $T.m$ does not exist, or if $F$ is not a function type, the s
tatic type of $i$ is \DYNAMIC{}; otherwise the static type of $i$ is the declare
d return type of $F$. |
| 3557 %\item Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static war
ning if $F$ is not a supertype of $(T_1, \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldot
s, T_{n+k}$ $x_{n+k}]) \to \bot$. |
| 3558 %\end{itemize} |
| 3559 |
| 3560 |
| 3561 %\subsubsection{This Invocation} |
| 3562 % Maybe this has no significance the way the language is set up? |
| 3563 |
| 3564 |
| 3565 \subsubsection{Cascaded Invocations} |
| 3566 \label{cascadedInvocations} |
| 3567 |
| 3568 A {\em cascaded method invocation} has the form {\em e..suffix} |
| 3569 where $e$ is an expression and {\em suffix} is a sequence of operator, method, g
etter or setter invocations. |
| 3570 |
| 3571 \begin{grammar} |
| 3572 {\bf cascadeSection:} |
| 3573 `{\escapegrammar ..}' (cascadeSelector arguments*) (assignableSelector arg
uments*)* (assignmentOperator expressionWithoutCascade)? |
| 3574 . |
| 3575 |
| 3576 {\bf cascadeSelector:}`[' expression `]'; |
| 3577 identifier |
| 3578 . |
| 3579 \end{grammar} |
| 3580 |
| 3581 A cascaded method invocation expression of the form {\em e..suffix} is equivalen
t to the expression \code{(t)\{t.{\em suffix}; \RETURN{} t;\}($e$)}. |
| 3582 |
| 3583 \subsubsection{Static Invocation} |
| 3584 \label{staticInvocation} |
| 3585 |
| 3586 A static method invocation $i$ has the form |
| 3587 $C.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ where $C$
denotes a class in the current scope. |
| 3588 |
| 3589 It is a static warning if $C$ does not declare a static method or getter $m$. |
| 3590 |
| 3591 \rationale{ |
| 3592 Note that the absence of $C.m$ is statically detectable. Nevertheless, we choose
not to define this situation as an error. The goal is to allow coding to proce
ed in the order that suits the developer rather than eagerly insisting on consis
tency. The warnings are given statically at compile-time to help developers catc
h errors. However, developers need not correct these problems immediately in ord
er to make progress. |
| 3593 } |
| 3594 |
| 3595 \commentary{ |
| 3596 Note the requirement that $C$ {\em declare} the method. This means that static m
ethods declared in superclasses of $C$ cannot be invoked via $C$. |
| 3597 } |
| 3598 |
| 3599 |
| 3600 Evaluation of $i$ proceeds as follows: |
| 3601 |
| 3602 If $C$ does not declare a static method or getter $m$ then the argument list $(a
_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated, af
ter which a \code{NoSuchMethodError} is thrown. |
| 3603 |
| 3604 Otherwise, evaluation proceeds as follows: |
| 3605 \begin{itemize} |
| 3606 \item |
| 3607 If the member $m$ declared by $C$ is a getter, then $i$ is equivalent to the exp
ression $(C.m)(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$.
|
| 3608 \item Otherwise, let $f$ be the the method $m$ declared in class $C$. Next, the
argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$
is evaluated. |
| 3609 The body of $f$ is then executed with respect to the bindings that resulted from
the evaluation of the argument list. The value of $i$ is the value returned aft
er the body of $f$ is executed. |
| 3610 \end{itemize} |
| 3611 |
| 3612 It is a static type warning if the type $F$ of $C.m$ may not be assigned to a fu
nction type. If $F$ is not a function type, or if $C.m$ does not exist, the sta
tic type of $i$ is \DYNAMIC{}. Otherwise |
| 3613 the static type of $i$ is the declared return type of $F$. |
| 3614 %\item Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static war
ning if $F$ is not a supertype of $(T_1, \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldot
s, T_{n+k}$ $x_{n+k}]) \to \bot$. |
| 3615 %\end{itemize} |
| 3616 |
| 3617 |
| 3618 |
| 3619 \subsubsection{Super Invocation} |
| 3620 \label{superInvocation} |
| 3621 |
| 3622 A super method invocation $i$ has the form |
| 3623 |
| 3624 $\SUPER{}.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. |
| 3625 |
| 3626 Evaluation of $i$ proceeds as follows: |
| 3627 |
| 3628 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}
: a_{n+k})$ is evaluated yielding actual argument objects $o_1, \ldots , o_{n+k
}$. Let $S$ be the superclass of the immediately enclosing class, and let $f$ be
the result of looking up method (\ref{ordinaryInvocation}) $m$ in $S$ with re
spect to the current library $L$. |
| 3629 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$. |
| 3630 |
| 3631 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. |
| 3632 |
| 3633 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. |
| 3634 |
| 3635 If the method lookup has failed, then let $g$ be the result of looking up getter
(\ref{getterAndSetterLookup}) $m$ in $S$ with respect to $L$. If the getter loo
kup succeeded, let $v_g$ be the value of the getter invocation $\SUPER{}.m$. The
n the value of $i$ is the result of invoking |
| 3636 the static method \code{Function.apply()} with arguments $v.g, [o_1, \ldots , o_
n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$. |
| 3637 |
| 3638 If getter lookup has also failed, then a new instance $im$ of the predefined c
lass \code{Invocation} is created, such that : |
| 3639 \begin{itemize} |
| 3640 \item \code{im.isMethod} evaluates to \code{\TRUE{}}. |
| 3641 \item \code{im.memberName} evaluates to \code{'m'}. |
| 3642 \item \code{im.positionalArguments} evaluates to an immutable list with the same
values as \code{[$o_1, \ldots, o_n$]}. |
| 3643 \item \code{im.namedArguments} evaluates to an immutable map with the same keys
and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}. |
| 3644 \end{itemize} |
| 3645 Then the method \code{noSuchMethod()} is looked up in $S$ and invoked on \THIS{}
with argument $im$, and the result of this invocation is the result of evaluati
ng $i$. |
| 3646 |
| 3647 It is a compile-time error if a super method invocation occurs in a top-level fu
nction or variable initializer, in an instance variable initializer or initializ
er list, in class \code{Object}, in a factory constructor or in a static method
or variable initializer. |
| 3648 |
| 3649 It is a static type warning if $S$ does not have an accessible (\ref{privacy}) i
nstance member named $m$. If $S.m$ exists, it is a static type warning if the t
ype $F$ of $S.m$ may not be assigned to a function type. If $S.m$ does not exist
, or if $F$ is not a function type, the static type of $i$ is \DYNAMIC{}; otherw
ise the static type of $i$ is the declared return type of $F$. |
| 3650 %\item Let $T_i$ be the static type of $a_i, i \in 1 .. n+k$. It is a static war
ning if $F$ is not a supertype of $(T_1, \ldots, t_n, [T_{n+1}$ $x_{n+1}, \ldot
s, T_{n+k}$ $x_{n+k}]) \to \bot$. |
| 3651 %\end{itemize} |
| 3652 |
| 3653 |
| 3654 |
| 3655 \subsubsection{Sending Messages} |
| 3656 |
| 3657 \label{sendingMessages} |
| 3658 |
| 3659 Messages are the sole means of communication among isolates. Messages are sent b
y invoking specific methods in the Dart libraries; there is no specific syntax
for sending a message. |
| 3660 |
| 3661 \commentary{In other words, the methods supporting sending messages embody primi
tives of Dart that are not accessible to ordinary code, much like the methods th
at spawn isolates. |
| 3662 } |
| 3663 |
| 3664 |
| 3665 \subsection{ Getter and Setter Lookup} |
| 3666 \label{getterAndSetterLookup} |
| 3667 |
| 3668 The result of a lookup of a getter (respectively setter) $m$ in object $o$ with
respect to library $L$ is the result of looking up getter (respectively sette
r) $m$ in class $C$ with respect to $L$, where $C$ is the class of $o$. |
| 3669 |
| 3670 The result of a lookup of a getter (respectively setter) $m$ in class $C$ with
respect to library $L$ is: |
| 3671 If $C$ declares a concrete instance getter (respectively setter) named $m$ that
is accessible to $L$, then that getter (respectively setter) is the result of
the lookup. Otherwise, if $C$ has a superclass $S$, then the result of the looku
p is the result of looking up getter (respectively setter) $m$ in $S$ with respe
ct to $L$. Otherwise, we say that the lookup has failed. |
| 3672 |
| 3673 \rationale { |
| 3674 The motivation for skipping abstract members during lookup is largely to allow s
moother mixin composition. |
| 3675 } |
| 3676 |
| 3677 \subsection{ Getter Invocation} |
| 3678 \label{getterInvocation} |
| 3679 |
| 3680 A getter invocation provides access to the value of a property. |
| 3681 |
| 3682 Evaluation of a getter invocation $i$ of the form $e.m$ proceeds as follows: |
| 3683 |
| 3684 First, the expression $e$ is evaluated to an object $o$. Then, the getter functi
on (\ref{getters}) $m$ is looked up (\ref{getterAndSetterLookup}) in $o$ with r
espect to the current library, and its body is executed with \THIS{} bound to $
o$. The value of the getter invocation expression is the result returned by the
call to the getter function. |
| 3685 |
| 3686 |
| 3687 If the getter lookup has failed, then a new instance $im$ of the predefined cla
ss \code{Invocation} is created, such that : |
| 3688 \begin{itemize} |
| 3689 \item \code{im.isGetter} evaluates to \code{\TRUE{}}. |
| 3690 \item \code{im.memberName} evaluates to \code{'m'}. |
| 3691 \item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []}
. |
| 3692 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
| 3693 \end{itemize} |
| 3694 Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with argu
ment $im$, and the result of this invocation is the result of evaluating $i$. |
| 3695 |
| 3696 Let $T$ be the static type of $e$. It is a static type warning if $T$ does not
have a getter named $m$. The static type of $i$ is the declared return type of $
T.m$, if $T.m$ exists; otherwise the static type of $i$ is \DYNAMIC{}. |
| 3697 |
| 3698 Evaluation of a getter invocation $i$ of the form $C.m$ proceeds as follows: |
| 3699 |
| 3700 If there is no class $C$ in the enclosing lexical scope of $i$, or if $C$ does
not declare, implicitly or explicitly, a getter named $m$, then a \code{NoSuchM
ethodError} is thrown. |
| 3701 Otherwise, the getter function $C.m$ is invoked. The value of $i$ is the result
returned by the call to the getter function. |
| 3702 |
| 3703 It is a static warning if there is no class $C$ in the enclosing lexical scope
of $i$, or if $C$ does not declare, implicitly or explicitly, a getter named $m
$. The static type of $i$ is the declared return type of $C.m$ if it exists or \
DYNAMIC{} otherwise. |
| 3704 |
| 3705 Evaluation of a top-level getter invocation $i$ of the form $m$, where $m$ is an
identifier, proceeds as follows: |
| 3706 |
| 3707 The getter function $m$ is invoked. The value of $i$ is the result returned by t
he call to the getter function. |
| 3708 \commentary{ |
| 3709 Note that the invocation is always defined. Per the rules for identifier referen
ces, an identifier will not be treated as a top-level getter invocation unless t
he getter $i$ is defined. |
| 3710 } |
| 3711 |
| 3712 The static type of $i$ is the declared return type of $m$. |
| 3713 |
| 3714 Evaluation of super getter invocation $i$ of the form $\SUPER{}.m$ proceeds as f
ollows: |
| 3715 |
| 3716 Let $S$ be the superclass of the immediately enclosing class. The getter functio
n (\ref{getters}) $m$ is looked up (\ref{getterAndSetterLookup}) in $S$ with re
spect to the current library, and its body is executed with \THIS{} bound to th
e current value of \THIS{}. The value of the getter invocation expression is t
he result returned by the call to the getter function. |
| 3717 |
| 3718 If the getter lookup has failed, then a new instance $im$ of the predefined cla
ss \code{Invocation} is created, such that : |
| 3719 \begin{itemize} |
| 3720 \item \code{im.isGetter} evaluates to \code{\TRUE{}}. |
| 3721 \item \code{im.memberName} evaluates to \code{'m'}. |
| 3722 \item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []}
. |
| 3723 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
| 3724 \end{itemize} |
| 3725 Then the method \code{noSuchMethod()} is looked up in $S$ and invoked with argu
ment $im$, and the result of this invocation is the result of evaluating $i$. |
| 3726 |
| 3727 It is a static type warning if $S$ does not have a getter named $m$. The static
type of $i$ is the declared return type of $S.m$, if $S.m$ exists; otherwise th
e static type of $i$ is \DYNAMIC{}. |
| 3728 |
| 3729 |
| 3730 |
| 3731 |
| 3732 \subsection{ Assignment} |
| 3733 \label{assignment} |
| 3734 |
| 3735 An assignment changes the value associated with a mutable variable or property. |
| 3736 |
| 3737 \begin{grammar} |
| 3738 {\bf assignmentOperator:}`=' ; |
| 3739 compoundAssignmentOperator |
| 3740 . |
| 3741 \end{grammar} |
| 3742 |
| 3743 Evaluation of an assignment $a$ of the form $v$ \code{=} $e$ proceeds as follows
: |
| 3744 |
| 3745 |
| 3746 If there is neither a local variable declaration with name $v$ nor a setter decl
aration with name $v=$ in the lexical scope enclosing $a$, then: |
| 3747 \begin{itemize} |
| 3748 \item If $a$ occurs inside a top level or static function (be it function, met
hod, getter, or setter) or variable initializer, evaluation of $a$ causes $e$ t
o be evaluated, after which a \code{NoSuchMethodError} is thrown. \item Otherwis
e, the assignment is equivalent to the assignment \code{ \THIS{}.$v$ = $e$}. |
| 3749 \end{itemize} |
| 3750 |
| 3751 Otherwise, let $d$ be the innermost declaration whose name is $v$, if it exist
s. |
| 3752 |
| 3753 If $d$ is the declaration of a local variable, the expression $e$ is evaluated t
o an object $o$. Then, the variable $v$ is bound to $o$. The value of the assign
ment expression is $o$. |
| 3754 |
| 3755 If $d$ is the declaration of a library variable, the expression $e$ is evaluated
to an object $o$. Then the setter $v=$ is invoked with its formal parameter bou
nd to $o$. The value of the assignment expression is $o$. |
| 3756 |
| 3757 Otherwise, if $d$ is the declaration of a static variable in class $C$, then the
assignment is equivalent to the assignment \code{$C.v$ = $e$}. |
| 3758 |
| 3759 Otherwise, the assignment is equivalent to the assignment \code{ \THIS{}.$v$ = $
e$}. |
| 3760 |
| 3761 In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interf
ace of the class of $o$ is not a subtype of the actual type (\ref{actualTypeOfAD
eclaration}) of $v$. |
| 3762 |
| 3763 It is a static type warning if the static type of $e$ may not be assigned to the
static type of $v$. The static type of the expression $v$ \code{=} $e$ is the s
tatic type of $e$. |
| 3764 |
| 3765 Evaluation of an assignment of the form $C.v$ \code{=} $e$ proceeds as follows: |
| 3766 |
| 3767 If $C$ does not denote a class available in the current scope, the assignment is
treated as an assignment $e_1.v= e$, where $e_1$ is the expression $C$. Otherw
ise, |
| 3768 the expression $e$ is evaluated to an object $o$. |
| 3769 If |
| 3770 %there is no class $C$ in the enclosing lexical scope of the assignment, or if |
| 3771 $C$ does not declare, implicitly or explicitly, a setter $v=$, then a \code{NoSu
chMethodError} is thrown. Otherwise, the setter $C.v=$ is invoked with its forma
l parameter bound to $o$. The value of the assignment expression is $o$. |
| 3772 |
| 3773 It is a static warning if |
| 3774 % there is no class $C$ in the enclosing lexical scope of the assignment, or if |
| 3775 $C$ does not declare, implicitly or explicitly, a setter $v=$. |
| 3776 |
| 3777 %\commentary{As of this writing, implementations treat the above situation as a
compile-time error.} |
| 3778 |
| 3779 In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the interf
ace of the class of $o$ is not a subtype of the declared static type of $C.v$. |
| 3780 |
| 3781 It is a static type warning if the static type of $e$ may not be assigned to the
static type of $C.v$. The static type of the expression $C.v$ \code{=} $e$ is
the static type of $e$. |
| 3782 |
| 3783 Evaluation of an assignment of the form $e_1.v$ \code{=} $e_2$ proceeds as follo
ws: |
| 3784 |
| 3785 The expression $e_1$ is evaluated to an object $o_1$. Then, the expression $e_2$
is evaluated to an object $o_2$. Then, the setter $v=$ is looked up (\ref{gett
erAndSetterLookup}) in $o_1$ with respect to the current library, and its body i
s executed with its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$. |
| 3786 |
| 3787 If the setter lookup has failed, then a new instance $im$ of the predefined cla
ss \code{Invocation} is created, such that : |
| 3788 \begin{itemize} |
| 3789 \item \code{im.isSetter} evaluates to \code{\TRUE{}}. |
| 3790 \item \code{im.memberName} evaluates to \code{'v='}. |
| 3791 \item \code{im.positionalArguments} evaluates to an immutable list with the same
values as \code{[$o_2$]}. |
| 3792 \item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
| 3793 \end{itemize} |
| 3794 |
| 3795 Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked with ar
gument $im$. The value of the assignment expression is $o_2$ irrespective of whe
ther setter lookup has failed or succeeded. |
| 3796 |
| 3797 In checked mode, it is a dynamic type error if $o_2$ is not \NULL{} and the inte
rface of the class of $o_2$ is not a subtype of the actual type of $e_1.v$. |
| 3798 |
| 3799 Let $T$ be the static type of $e_1$. It is a static type warning if $T$ does not
have an accessible instance setter named $v=$. It is a static type warning if t
he static type of $e_2$ may not be assigned to $T$. The static type of the exp
ression $e_1v$ \code{=} $e_2$ is the static type of $e_2$. |
| 3800 |
| 3801 Evaluation of an assignment of the form $e_1[e_2]$ \code{=} $e_3$ is equivalent
to the evaluation of the expression \code{(a, i, e)\{a.[]=(i, e); \RETURN{} e; \
} ($e_1, e_2, e_3$)}. The static type of the expression $e_1[e_2]$ \code{=} $e_
3$ is the static type of $e_3$. |
| 3802 |
| 3803 % Should we add: It is a dynamic error if $e_1$ evaluates to an constant list o
r map. |
| 3804 |
| 3805 It is as static warning if an assignment of the form $v = e$ occurs inside a top
level or static function (be it function, method, getter, or setter) or variabl
e initializer and there is neither a local variable declaration with name $v$ n
or setter declaration with name $v=$ in the lexical scope enclosing the assignme
nt. |
| 3806 |
| 3807 |
| 3808 |
| 3809 \subsubsection{Compound Assignment} |
| 3810 \label{compoundAssignment} |
| 3811 |
| 3812 A compound assignment of the form $v$ $op\code{=} e$ is equivalent to $v \code{=
} v$ $op$ $e$. A compound assignment of the form $C.v$ $op \code{=} e$ is equiva
lent to $C.v \code{=} C.v$ $op$ $e$. A compound assignment of the form $e_1.v$ $
op = e_2$ is equivalent to \code{((x) $=>$ x.v = x.v $op$ $e_2$)($e_1$)} where $
x$ is a variable that is not used in $e_2$. A compound assignment of the form $
e_1[e_2]$ $op\code{=} e_3$ is equivalent to |
| 3813 \code{((a, i) $=>$ a[i] = a[i] $op$ $e_3$)($e_1, e_2$)} where $a$ and $i$ are a
variables that are not used in $e_3$. |
| 3814 |
| 3815 \begin{grammar} |
| 3816 {\bf compoundAssignmentOperator:}`*='; |
| 3817 `/='; |
| 3818 `\~{}/='; |
| 3819 `\%='; |
| 3820 `+='; |
| 3821 `-='; |
| 3822 `{\escapegrammar \lt \lt}='; |
| 3823 `{\escapegrammar \gt \gt}='; |
| 3824 `\&='; |
| 3825 `\^{}='; |
| 3826 `$|$=' |
| 3827 . |
| 3828 \end{grammar} |
| 3829 |
| 3830 |
| 3831 \subsection{ Conditional} |
| 3832 \label{conditional} |
| 3833 |
| 3834 A {\em conditional expression} evaluates one of two expressions based on a boole
an condition. |
| 3835 |
| 3836 \begin{grammar} |
| 3837 {\bf conditionalExpression:} |
| 3838 logicalOrExpression (`?' expressionWithoutCascade `{\escapegrammar :}' expr
essionWithoutCascade)? |
| 3839 . % the first branches could top level expressions, it seems, but certainl
y NOT the second |
| 3840 \end{grammar} |
| 3841 |
| 3842 Evaluation of a conditional expression $c$ of the form $e_1 ? e_2 : e_3$ proceed
s as follows: |
| 3843 |
| 3844 First, $e_1$ is evaluated to an object $o_1$. Then, $o_1$ is subjected to bool
ean conversion (\ref{booleanConversion}) producing an object $r$. If $r$ is tru
e, then the value of $c$ is the result of evaluating the expression $e_2$. Other
wise the value of $c$ is the result of evaluating the expression $e_3$. |
| 3845 |
| 3846 If all of the following hold: |
| 3847 \begin{itemize} |
| 3848 \item $e_1$ shows that a variable $v$ has type $T$. |
| 3849 \item $v$ is not potentially mutated in either $e_1$, $e_2$ or within a closure. |
| 3850 \item If the variable $v$ is accessed by a closure in $e_2$ then the variable $v
$ is not potentially mutated anywhere in the scope of $v$. |
| 3851 \end{itemize} |
| 3852 |
| 3853 then the type of $v$ is known to be $T$ in $e_2$. |
| 3854 |
| 3855 |
| 3856 It is a static type warning if the type of $e_1$ may not be assigned to \code{b
ool}. The static type of $c$ is the least upper bound (\ref{leastUpperBounds})
of the static type of $e_2$ and the static type of $e_3$. |
| 3857 |
| 3858 |
| 3859 \subsection{ Logical Boolean Expressions} |
| 3860 \label{logicalBooleanExpressions} |
| 3861 |
| 3862 The logical boolean expressions combine boolean objects using the boolean conjun
ction and disjunction operators. |
| 3863 |
| 3864 \begin{grammar} |
| 3865 {\bf logicalOrExpression:} |
| 3866 logicalAndExpression (`$||$' logicalAndExpression)* |
| 3867 . |
| 3868 |
| 3869 |
| 3870 {\bf logicalAndExpression:} |
| 3871 equalityExpression (`\&\&' equalityExpression)* |
| 3872 % bitwiseOrExpression (`\&\&' bitwiseOrExpression)* |
| 3873 . |
| 3874 \end{grammar} |
| 3875 |
| 3876 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$. |
| 3877 |
| 3878 Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes t
he evaluation of $e_1$; if $e_1$ evaluates to true, the result of evaluating $b$
is true, otherwise $e_2$ is evaluated to an object $o$, which is then subjected
to boolean conversion (\ref{booleanConversion}) producing an object $r$, which
is the value of $b$. |
| 3879 |
| 3880 Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes
the evaluation of $e_1$; if $e_1$ does not evaluate to true, the result of eval
uating $b$ is false, otherwise $e_2$ is evaluated to an object $o$, which is the
n subjected to boolean conversion producing an object $r$, which is the value of
$b$. |
| 3881 |
| 3882 A logical boolean expression $b$ of the form $e_1 \&\& e_2$ shows that a variabl
e $v$ has type |
| 3883 $T$ if all of the following conditions hold: |
| 3884 \begin{itemize} |
| 3885 \item Either $e_1$ shows that $v$ has type $T$ or $e_2$ shows that $v$ has type
$T$. |
| 3886 \item $v$ is a local variable or formal parameter. |
| 3887 \item The variable $v$ is not mutated in either $e_1$ or $e_2$ or within a closu
re. |
| 3888 \end{itemize} |
| 3889 |
| 3890 Furthermore, if all of the following hold: |
| 3891 \begin{itemize} |
| 3892 \item $e_1$ shows that $v$ has type $T$. |
| 3893 \item $v$ is not mutated in either $e_1$, $e_2$ or within a closure. |
| 3894 \item If the variable $v$ is accessed by a closure in $e_2$ then the variable $v
$ is not potentially mutated anywhere in the scope of $v$. |
| 3895 \end{itemize} |
| 3896 then the type of $v$ is known to be $T$ in $e_2$. |
| 3897 |
| 3898 The static type of a logical boolean expression is \code{bool}. |
| 3899 |
| 3900 |
| 3901 \subsection{ Equality} |
| 3902 \label{equality} |
| 3903 |
| 3904 Equality expressions test objects for equality. |
| 3905 |
| 3906 \begin{grammar} |
| 3907 {\bf equalityExpression:}relationalExpression (equalityOperator relationalExpres
sion)?; |
| 3908 \SUPER{} equalityOperator relationalExpression |
| 3909 . |
| 3910 |
| 3911 {\bf equalityOperator:}`=='; |
| 3912 `!=' |
| 3913 . |
| 3914 \end{grammar} |
| 3915 |
| 3916 An {\em equality expression} is either a relational expression (\ref{relationalE
xpressions}), or an invocation of an equality operator on either \SUPER{} or an
expression $e_1$, with argument $e_2$. |
| 3917 |
| 3918 |
| 3919 Evaluation of an equality expression $ee$ of the form \code{$e_1$ == $e_2$} proc
eeds as follows: |
| 3920 \begin{itemize} |
| 3921 \item The expression $e_1$ is evaluated to an object $o_1$. |
| 3922 \item The expression $e_2$ is evaluated to an object $o_2$. |
| 3923 \item If either $o_1$ or $o_2$ is \NULL{}, then $ee$ evaluates to \code{identica
l($o_1$, $o_2$)}. Otherwise, |
| 3924 \item $ee$ is equivalent to the method invocation \code{$o_1$.==($o_2$)}. |
| 3925 \end{itemize} |
| 3926 |
| 3927 |
| 3928 Evaluation of an equality expression $ee$ of the form \code{\SUPER{} == $e$} pro
ceeds as follows: |
| 3929 \begin{itemize} |
| 3930 \item The expression $e$ is evaluated to an object $o$. |
| 3931 \item If either \THIS{} or $o$ is \NULL{}, then $ee$ evaluates to \code{identica
l(\THIS{}, $o$)}. Otherwise, |
| 3932 \item $ee$ is equivalent to the method invocation \code{\SUPER{}.==($o$)}. |
| 3933 \end{itemize} |
| 3934 |
| 3935 \commentary{As a result of the above definition, user defined \code{==} methods
can assume that their argument is non-null, and avoid the standard boiler-plate
prelude: |
| 3936 |
| 3937 \code{if (identical(\NULL{}, arg)) return \FALSE{};} |
| 3938 |
| 3939 Another implication is that there is never a need to use \code{identical()} to t
est against \NULL{}, nor should anyone ever worry about whether to write \NULL{}
== $e$ or $e$ == \NULL{}. |
| 3940 } |
| 3941 |
| 3942 An equality expression of the form \code{$e_1$ != $e_2$} is equivalent to the e
xpression \code{!($e_1$ == $e_2$)}. An equality expression of the form \code{\SU
PER{} != $e$} is equivalent to the expression \code{!(\SUPER{} == $e$)}. |
| 3943 |
| 3944 |
| 3945 |
| 3946 %The expression $e_1$ is evaluated to an object $o_1$; then the expression $e_2
$ is evaluated to an object $o_2$. Next, if $o_1$ and $o_2$ are the same object
, then $ee$ evaluates to \TRUE{}, otherwise $ee$ evaluates to \FALSE{}. |
| 3947 |
| 3948 |
| 3949 The static type of an equality expression is \code{bool}. |
| 3950 |
| 3951 |
| 3952 \subsection{ Relational Expressions} |
| 3953 \label{relationalExpressions} |
| 3954 |
| 3955 Relational expressions invoke the relational operators on objects. |
| 3956 |
| 3957 \begin{grammar} |
| 3958 {\bf relationalExpression:}bitwiseOrExpression (typeTest $|$ typeCast $|$ relat
ionalOperator bitwiseOrExpression)?; |
| 3959 \SUPER{} relationalOperator bitwiseOrExpression |
| 3960 . |
| 3961 |
| 3962 |
| 3963 {\bf relationalOperator:}`{\escapegrammar \gt=}'; |
| 3964 `{\escapegrammar \gt}'; |
| 3965 `{\escapegrammar \lt}='; |
| 3966 `{\escapegrammar \lt}' |
| 3967 . |
| 3968 \end{grammar} |
| 3969 |
| 3970 A {\em relational expression} is either a bitwise expression (\ref{bitwiseExpres
sions}), or an invocation of a relational operator on either \SUPER{} or an expr
ession $e_1$, with argument $e_2$. |
| 3971 |
| 3972 A relational expression of the form $e_1$ $op$ $e_2$ is equivalent to the metho
d invocation \code{$e_1$.$op$($e_2$)}. A relational expression of the form \SUP
ER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$
)}. |
| 3973 |
| 3974 \subsection{ Bitwise Expressions} |
| 3975 \label{bitwiseExpressions} |
| 3976 |
| 3977 Bitwise expressions invoke the bitwise operators on objects. |
| 3978 |
| 3979 \begin{grammar} |
| 3980 {\bf bitwiseOrExpression:}bitwiseXorExpression (`$|$' bitwiseXorExpression)*; |
| 3981 \SUPER{} (`$|$' bitwiseXorExpression)+ |
| 3982 . |
| 3983 |
| 3984 {\bf bitwiseXorExpression:}bitwiseAndExpression (`\^{}' bitwiseAndExpression)*; |
| 3985 \SUPER{} (`\^{}' bitwiseAndExpression)+ |
| 3986 . |
| 3987 |
| 3988 {\bf bitwiseAndExpression:}shiftExpression (`\&' shiftExpression)*; |
| 3989 \SUPER{} (`\&' shiftExpression)+ |
| 3990 . |
| 3991 |
| 3992 {\bf bitwiseOperator:}`\&'; |
| 3993 `\^{}'; |
| 3994 `$|$' |
| 3995 . |
| 3996 \end{grammar} |
| 3997 |
| 3998 A {\em bitwise expression} is either a shift expression (\ref{shift}), or an inv
ocation of a bitwise operator on either \SUPER{} or an expression $e_1$, with ar
gument $e_2$. |
| 3999 |
| 4000 A bitwise expression of the form $e_1$ $op$ $e_2$ is equivalent to the method
invocation $e_1.op(e_2)$. |
| 4001 A bitwise expression of the form \code{\SUPER{} $op$ $e_2$} is equivalent to th
e method invocation \code{\SUPER{}.op($e_2$)}. |
| 4002 |
| 4003 \commentary{ |
| 4004 It should be obvious that the static type rules for these expressions are define
d by the equivalence above - ergo, by the type rules for method invocation and t
he signatures of the operators on the type $e_1$. The same holds in similar situ
ations throughout this specification. |
| 4005 } |
| 4006 |
| 4007 |
| 4008 \subsection{ Shift} |
| 4009 \label{shift} |
| 4010 |
| 4011 Shift expressions invoke the shift operators on objects. |
| 4012 |
| 4013 \begin{grammar} |
| 4014 {\bf shiftExpression:}additiveExpression (shiftOperator additiveExpression)*; |
| 4015 \SUPER{} (shiftOperator additiveExpression)+ |
| 4016 . |
| 4017 |
| 4018 {\bf shiftOperator:}`{\escapegrammar \lt\lt'}; |
| 4019 `{\escapegrammar \gt \gt}' |
| 4020 . |
| 4021 \end{grammar} |
| 4022 |
| 4023 A {\em shift expression} is either an additive expression (\ref{additiveExpressi
ons}), or an invocation of a shift operator on either \SUPER{} or an expression
$e_1$, with argument $e_2$. |
| 4024 |
| 4025 A shift expression of the form $e_1$ $op$ $e_2$ is equivalent to the method in
vocation \code{$e_1$.$op$($e_2$)}. A shift expression of the form \SUPER{} $op$
$e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)}. |
| 4026 |
| 4027 \commentary{ |
| 4028 Note that this definition implies left-to-right evaluation order among shift exp
ressions: |
| 4029 |
| 4030 $e_1 << e_2 << e_3$ |
| 4031 |
| 4032 is evaluated as $(e_1 << e_2 ).<< (e_3)$ which is equivalent to $(e_1 << e_2)
<< e_3$. |
| 4033 The same holds for additive and multiplicative expressions. |
| 4034 } |
| 4035 |
| 4036 \subsection{ Additive Expressions} |
| 4037 \label{additiveExpressions} |
| 4038 |
| 4039 Additive expressions invoke the addition operators on objects. |
| 4040 |
| 4041 \begin{grammar} |
| 4042 {\bf additiveExpression:}multiplicativeExpression (additiveOperator multiplicati
veExpression)*; |
| 4043 \SUPER{} (additiveOperator multiplicativeExpression)+ |
| 4044 . |
| 4045 |
| 4046 {\bf additiveOperator:}`+'; |
| 4047 `-' |
| 4048 . |
| 4049 \end{grammar} |
| 4050 |
| 4051 An {\em additive expression} is either a multiplicative expression (\ref{multipl
icativeExpressions}), or an invocation of an additive operator on either \SUPER{
} or an expression $e_1$, with argument $e_2$. |
| 4052 |
| 4053 An additive expression of the form $e_1$ $op$ $e_2$ is equivalent to the method
invocation \code{$e_1$.$op$($e_2$)}. An additive expression of the form \SUPER
{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)}
. |
| 4054 |
| 4055 The static type of an additive expression is usually determined by the signature
given in the declaration of the operator used. However, invocations of the oper
ators \cd{+} and \cd{-} of class \cd{int} are treated specially by the typechec
ker. The static type of an expression $e_1 + e_2$ where $e_1$ has static type \c
d{int} is \cd{int} if the static type of $e_2$ is \cd{int}, and \cd{double} if t
he static type of $e_2$ is \cd{double}. The static type of an expression $e_1 -
e_2$ where $e_1$ has static type \cd{int} is \cd{int} if the static type of $e_2
$ is \cd{int}, and \cd{double} if the static type of $e_2$ is \cd{double}. |
| 4056 |
| 4057 |
| 4058 \subsection{ Multiplicative Expressions} |
| 4059 \label{multiplicativeExpressions} |
| 4060 |
| 4061 Multiplicative expressions invoke the multiplication operators on objects. |
| 4062 |
| 4063 \begin{grammar} |
| 4064 {\bf multiplicativeExpression:}unaryExpression (multiplicativeOperator unaryExpr
ession)*; |
| 4065 \SUPER{} (multiplicativeOperator unaryExpression)+ |
| 4066 . |
| 4067 |
| 4068 {\bf multiplicativeOperator:}`*'; |
| 4069 `/'; |
| 4070 `\%'; |
| 4071 `\~{}/' |
| 4072 . |
| 4073 |
| 4074 \end{grammar} |
| 4075 |
| 4076 A {\em multiplicative expression} is either a unary expression (\ref{unaryExpre
ssions}), or an invocation of a multiplicative operator on either \SUPER{} or an
expression $e_1$, with argument $e_2$. |
| 4077 |
| 4078 A multiplicative expression of the form $e_1$ $op$ $e_2$ is equivalent to the
method invocation \code{$e_1$.$op$($e_2$)}. A multiplicative expression of the f
orm \SUPER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$
op$($e_2$)}. |
| 4079 |
| 4080 The static type of an multiplicative expression is usually determined by the sig
nature given in the declaration of the operator used. However, invocations of th
e operators \cd{*}, \cd{\%} and \cd{\~{}/} of class \cd{int} are treated specia
lly by the typechecker. The static type of an expression $e_1 * e_2$ where $e_1$
has static type \cd{int} is \cd{int} if the static type of $e_2$ is \cd{int}, a
nd \cd{double} if the static type of $e_2$ is \cd{double}. The static type of an
expression $e_1 \% e_2$ where $e_1$ has static type \cd{int} is \cd{int} if the
static type of $e_2$ is \cd{int}, and \cd{double} if the static type of $e_2$ i
s \cd{double}. The static type of an expression \cd{$e_1$ \~{}/ $e_2$} where $e
_1$ has static type \cd{int} is \cd{int} if the static type of $e_2$ is \cd{int}
. |
| 4081 |
| 4082 \subsection{ Unary Expressions} |
| 4083 \label{unaryExpressions} |
| 4084 |
| 4085 Unary expressions invoke unary operators on objects. |
| 4086 |
| 4087 \begin{grammar} |
| 4088 {\bf unaryExpression:}prefixOperator unaryExpression; |
| 4089 postfixExpression; |
| 4090 prefixOperator \SUPER{}; |
| 4091 incrementOperator assignableExpression |
| 4092 . |
| 4093 |
| 4094 {\bf prefixOperator:}`-'; |
| 4095 unaryOperator |
| 4096 . |
| 4097 |
| 4098 {\bf unaryOperator:}`!' ; |
| 4099 `\~{}' |
| 4100 . |
| 4101 |
| 4102 |
| 4103 \end{grammar} |
| 4104 |
| 4105 A {\em unary expression} is either aa postfix expression (\ref{postfixExpressio
ns}), an invocation of a prefix operator on an expression or an invocation of a
unary operator on either \SUPER{} or an expression $e$. |
| 4106 |
| 4107 The expression $!e$ is equivalent to the expression $e? \FALSE{} :\TRUE{}$. |
| 4108 |
| 4109 Evaluation of an expression of the form \code{++$e$} is equivalent to \code{$e$
+= 1}. Evaluation of an expression of the form \code{-{}-$e$} is equivalent to
\code{$e$ -= 1}. |
| 4110 |
| 4111 %The expression $-e$ is equivalent to the method invocation \code{$e$.-()}. The
expression \code{-\SUPER{}} is equivalent to the method invocation \code{\SUPE
R{}.-()}. |
| 4112 |
| 4113 An expression of the form \code{$op$ $e$} is equivalent to the method invocation
\code{$e.op()$}. An expression of the form \code{$op$ \SUPER{}} is equivalent t
o the method invocation \code{\SUPER{}.$op()$}. |
| 4114 |
| 4115 |
| 4116 |
| 4117 \subsection{ Postfix Expressions} |
| 4118 \label{postfixExpressions} |
| 4119 |
| 4120 Postfix expressions invoke the postfix operators on objects. |
| 4121 |
| 4122 \begin{grammar} |
| 4123 {\bf postfixExpression:}assignableExpression postfixOperator; |
| 4124 primary selector* |
| 4125 . |
| 4126 |
| 4127 {\bf postfixOperator:} |
| 4128 incrementOperator |
| 4129 . |
| 4130 |
| 4131 {\bf selector:}assignableSelector; |
| 4132 arguments |
| 4133 . |
| 4134 |
| 4135 {\bf incrementOperator:}`++'; |
| 4136 `-{}-' |
| 4137 . |
| 4138 |
| 4139 \end{grammar} |
| 4140 |
| 4141 A {\em postfix expression} is either a primary expression, a function, method o
r getter invocation, or an invocation of a postfix operator on an expression $e$
. |
| 4142 |
| 4143 A postfix expression of the form \code{$v$++}, where $v$ is an identifier, is eq
uivalent to \code{()\{var r = $v$; $v$ = r + 1; return r\}()}. |
| 4144 |
| 4145 \rationale{The above ensures that if $v$ is a field, the getter gets called exac
tly once. Likewise in the cases below. |
| 4146 } |
| 4147 |
| 4148 A postfix expression of the form \code{$C.v$ ++} is equivalent to \code{()\{var
r = $C.v$; $C.v$ = r + 1; return r\}()}. |
| 4149 |
| 4150 A postfix expression of the form \code{$e_1.v$++} is equivalent to \code{(x)\{va
r r = x.v; x.v = r + 1; \RETURN{} r\}($e_1$)}. |
| 4151 |
| 4152 A postfix expression of the form \code{$e_1[e_2]$++}, is equivalent to \code{(a
, i)\{var r = a[i]; a[i] = r + 1; return r\}($e_1$, $e_2$)}. |
| 4153 |
| 4154 A postfix expression of the form \code{$v$-{}-}, where $v$ is an identifier, is
equivalent to \code{()\{var r = $v$; $v$ = r - 1; return r\}()}. |
| 4155 |
| 4156 A postfix expression of the form \code{$C.v$-{}-} is equivalent to \code{()\{var
r = $C.v$; $C.v$ = r - 1; return r\}()}. |
| 4157 |
| 4158 A postfix expression of the form \code{$e_1.v$-{}-} is equivalent to \code{(x)\{
var r = x.v; x.v = r - 1; \RETURN{} r\}($e_1$)}. |
| 4159 |
| 4160 A postfix expression of the form \code{$e_1[e_2]$-{}-}, is equivalent to \code{
(a, i)\{var r = a[i]; a[i] = r - 1; return r\}($e_1$, $e_2$)}. |
| 4161 |
| 4162 |
| 4163 \subsection{ Assignable Expressions} |
| 4164 \label{assignableExpressions} |
| 4165 |
| 4166 Assignable expressions are expressions that can appear on the left hand side of
an assignment. |
| 4167 This section describes how to evaluate these expressions when they do not consti
tute the complete left hand side of an assignment. |
| 4168 |
| 4169 \rationale{ |
| 4170 Of course, if assignable expressions always appeared {\em as} the left hand side
, one would have no need for their value, and the rules for evaluating them woul
d be unnecessary. However, assignable expressions can be subexpressions of othe
r expressions and therefore must be evaluated. |
| 4171 } |
| 4172 |
| 4173 |
| 4174 |
| 4175 \begin{grammar} |
| 4176 |
| 4177 {\bf assignableExpression:}primary (argument* assignableSelector)+; |
| 4178 \SUPER{} assignableSelector; |
| 4179 identifier |
| 4180 . |
| 4181 |
| 4182 {\bf assignableSelector:}`[' expression `]'; % again, could be top level |
| 4183 `{\escapegrammar .}' identifier |
| 4184 . |
| 4185 |
| 4186 \end{grammar} |
| 4187 |
| 4188 An {\em assignable expression} is either: |
| 4189 \begin{itemize} |
| 4190 \item An identifier. |
| 4191 \item An invocation of a getter (\ref{getters}) or list access operator on an ex
pression $e$. |
| 4192 \item An invocation of a getter or list access operator on \SUPER{}. |
| 4193 \end{itemize} |
| 4194 |
| 4195 |
| 4196 An assignable expression of the form $id$ is evaluated as an identifier expressi
on (\ref{identifierReference}). |
| 4197 |
| 4198 %An assignable expression of the form $e.id(a_1, \ldots, a_n)$ is evaluated as a
method invocation (\ref{methodInvocation}). |
| 4199 |
| 4200 An assignable expression of the form $e.id$ is evaluated as a getter invocation
(\ref{getterInvocation}). |
| 4201 |
| 4202 An assignable expression of the form \code{$e_1$[$e_2$]} is evaluated as a metho
d invocation of the operator method \code{[]} on $e_1$ with argument $e_2$. |
| 4203 |
| 4204 An assignable expression of the form \code{\SUPER{}.id} is evaluated as a gette
r invocation. |
| 4205 |
| 4206 An assignable expression of the form \code{\SUPER{}[$e_2$]} is equivalent to the
method invocation \code{\SUPER{}.[]($e_2$)}. |
| 4207 |
| 4208 \subsection{ Identifier Reference} |
| 4209 \label{identifierReference} |
| 4210 |
| 4211 An {\em identifier expression} consists of a single identifier; it provides acce
ss to an object via an unqualified name. |
| 4212 |
| 4213 \begin{grammar} |
| 4214 {\bf identifier:} |
| 4215 IDENTIFIER |
| 4216 . |
| 4217 |
| 4218 |
| 4219 {\bf IDENTIFIER\_NO\_DOLLAR:} |
| 4220 IDENTIFIER\_START\_NO\_DOLLAR IDENTIFIER\_PART\_NO\_DOLLAR* |
| 4221 . |
| 4222 |
| 4223 {\bf IDENTIFIER:} |
| 4224 IDENTIFIER\_START IDENTIFIER\_PART* |
| 4225 . |
| 4226 |
| 4227 {\bf BUILT\_IN\_IDENTIFIER:} \ABSTRACT{}; |
| 4228 \AS{}; |
| 4229 % \ASSERT{}; |
| 4230 \DYNAMIC{}; |
| 4231 \EXPORT{}; |
| 4232 \EXTERNAL{}; |
| 4233 \FACTORY{}; |
| 4234 \GET{}; |
| 4235 \IMPLEMENTS{}; |
| 4236 \IMPORT{}; |
| 4237 \LIBRARY{}; |
| 4238 \OPERATOR{}; |
| 4239 \PART{}; |
| 4240 \SET{}; |
| 4241 \STATIC{}; |
| 4242 \TYPEDEF{} |
| 4243 . |
| 4244 |
| 4245 {\bf IDENTIFIER\_START:}IDENTIFIER\_START\_NO\_DOLLAR; |
| 4246 '\$' |
| 4247 . |
| 4248 |
| 4249 {\bf IDENTIFIER\_START\_NO\_DOLLAR:}LETTER; |
| 4250 '\_' |
| 4251 . |
| 4252 |
| 4253 {\bf IDENTIFIER\_PART\_NO\_DOLLAR:}IDENTIFIER\_START\_NO\_DOLLAR; |
| 4254 DIGIT |
| 4255 . |
| 4256 |
| 4257 |
| 4258 {\bf IDENTIFIER\_PART:}IDENTIFIER\_START; |
| 4259 DIGIT |
| 4260 . |
| 4261 |
| 4262 |
| 4263 |
| 4264 {\bf qualified:} |
| 4265 identifier (`{\escapegrammar .}' identifier)? |
| 4266 . |
| 4267 \end{grammar} |
| 4268 |
| 4269 A built-in identifier is one of the identifiers produced by the production {\em
BUILT\_IN\_IDENTIFIER}. It is a compile-time error if a built-in identifier is u
sed as the declared name of a class, type parameter or type alias. It is a compi
le-time error to use a built-in identifier other than \DYNAMIC{} as a type annot
ation. |
| 4270 |
| 4271 \rationale{ |
| 4272 Built-in identifiers are identifiers that are used as keywords in Dart, but are
not reserved words in Javascript. To minimize incompatibilities when porting Jav
ascript code to Dart, we do not make these into reserved words. A built-in ident
ifier may not be used to name a class or type. In other words, they are treated
as reserved words when used as types. This eliminates many confusing situations
without causing compatibility problems. After all, a Javascript program has no
type declarations or annotations so no clash can occur. Furthermore, types shou
ld begin with an uppercase letter (see the appendix) and so no clash should occu
r in any Dart user program anyway. |
| 4273 } |
| 4274 |
| 4275 Evaluation of an identifier expression $e$ of the form $id$ proceeds as follows: |
| 4276 |
| 4277 Let $d$ be the innermost declaration in the enclosing lexical scope whose name i
s $id$. If no such declaration exists in the lexical scope, let $d$ be the decl
aration of the inherited member named $id$ if it exists. |
| 4278 %If no such member exists, let $d$ be the declaration of the static member name
$id$ declared in a superclass of the current class, if it exists. |
| 4279 |
| 4280 \begin{itemize} |
| 4281 \item If $d$ is a class or type alias $T$, the value of $e$ is an instance of cl
ass \code{Type} reifying $T$. |
| 4282 \item If $d$ is a type parameter $T$, then the value of $e$ is the value of the
actual type argument corresponding to $T$ that was passed to the generative con
structor that created the current binding of \THIS{}. \commentary{ We are assure
d that \THIS{} is well defined, because if we were in a static member the refere
nce to $T$ would be a compile-time error (\ref{generics}.)} |
| 4283 %\item If $d$ is a library variable then: |
| 4284 % \begin{itemize} |
| 4285 % \item If $d$ is of one of the forms \code{\VAR{} $v$ = $e_i$;} , \code{$T$ $v
$ = $e_i$;} , \code{\FINAL{} $v$ = $e_i$;} or \code{\FINAL{} $T$ $v$ = $e_i$;}
and no value has yet been stored into $v$ then the initializer expression $e_i$
is evaluated. If, during the evaluation of $e_i$, the getter for $v$ is referenc
ed, a \code{CyclicInitializationError} is thrown. If the evaluation succeeded yi
elding an object $o$, let $r = o$, otherwise let $r = \NULL{}$. In any case, $r$
is stored into $v$. The value of $e$ is $r$. |
| 4286 \item If $d$ is a constant variable of one of the forms \code{\CONST{} $v$ =
$e$;} or \code{\CONST{} $T$ $v$ = $e$;} then the value $id$ is the value of the
compile-time constant $e$. |
| 4287 % Otherwise |
| 4288 % \item $e$ evaluates to the current binding of $id$. |
| 4289 % \end{itemize} |
| 4290 \item If $d$ is a local variable or formal parameter then $e$ evaluates to the c
urrent binding of $id$. |
| 4291 %\item If $d$ is a library variable, local variable, or formal parameter, then $
e$ evaluates to the current binding of $id$. \commentary{This case also applies
if d is a library or local function declaration, as these are equivalent to func
tion-valued variable declarations.} |
| 4292 \item If $d$ is a static method, top-level function or local function then $e$ e
valuates to the function defined by $d$. |
| 4293 \item If $d$ is the declaration of a static variable or static getter declared i
n class $C$, then $e$ is equivalent to the getter invocation (\ref{getterInvocat
ion}) $C.id$. |
| 4294 \item If $d$ is the declaration of a library variable or top-level getter, then
$e$ is equivalent to the getter invocation $id$. |
| 4295 \item Otherwise, if $e$ occurs inside a top level or static function (be it func
tion, method, getter, or setter) or variable initializer, evaluation of $e$ cau
ses a\code{NoSuchMethod} to be thrown. |
| 4296 \item Otherwise, $e$ is equivalent to the property extraction (\ref{propertyExtr
action}) \THIS{}.$id$. |
| 4297 % This implies that referring to an undefined static getter by simple name is an
error, whereas doing so by qualified name is only a warning. Same with assignme
nts. Revise? |
| 4298 \end{itemize} |
| 4299 |
| 4300 The static type of $e$ is determined as follows: |
| 4301 |
| 4302 \begin{itemize} |
| 4303 \item If $d$ is a class, type alias or type parameter the static type of $e$ is
\code{Type}. |
| 4304 \item If $d$ is a local variable or formal parameter the static type of $e$ is t
he type of the variable $id$, unless $id$ is known to have some type $T$, in whi
ch case the static type of $e$ is $T$, provided that $T$ is a subtype of any oth
er type $S$ such that $v$ is known to have type $S$. |
| 4305 \item If $d$ is a static method, top-level function or local function the static
type of $e$ the function type defined by $d$. |
| 4306 \item If $d$ is the declaration of a static variable or static getter declared i
n class $C$, the static type of $e$ the static type of the getter invocation (\r
ef{getterInvocation}) $C.id$. |
| 4307 \item If $d$ is the declaration of a library variable or top-level getter, the s
tatic type of $e$ is the static type of the getter invocation $id$. |
| 4308 \item Otherwise, if $e$ occurs inside a top level or static function (be it func
tion, method, getter, or setter) or variable initializer, the static type of $e
$ is \DYNAMIC{}. |
| 4309 \item Otherwise, the static type of $e$ is the type of the property extraction (
\ref{propertyExtraction}) \THIS{}.$id$. |
| 4310 \end{itemize} |
| 4311 |
| 4312 It is a static warning if an identifier expression $id$ occurs inside a top leve
l or static function (be it function, method, getter, or setter) or variable ini
tializer and there is no declaration $d$ with name $id$ in the lexical scope enc
losing the expression. |
| 4313 |
| 4314 \subsection{ Type Test} |
| 4315 \label{typeTest} |
| 4316 |
| 4317 The {\em is-expression} tests if an object is a member of a type. |
| 4318 |
| 4319 \begin{grammar} |
| 4320 {\bf typeTest:} |
| 4321 isOperator type |
| 4322 . |
| 4323 |
| 4324 |
| 4325 {\bf isOperator:} |
| 4326 \IS{} `!'? |
| 4327 . |
| 4328 \end{grammar} |
| 4329 |
| 4330 Evaluation of the is-expression \code{$e$ \IS{} $T$} proceeds as follows: |
| 4331 |
| 4332 The expression $e$ is evaluated to a value $v$. Then, if the interface of the cl
ass of $v$ is a subtype of $T$, the is-expression evaluates to true. Otherwise i
t evaluates to false. |
| 4333 |
| 4334 \commentary{It follows that \code{$e$ \IS{} Object} is always true. This makes s
ense in a language where everything is an object. |
| 4335 |
| 4336 Also note that \code{\NULL{} \IS{} $T$} is false unless $T = \code{Object}$, $T
= \code{\DYNAMIC{}}$ or $T = \code{Null}$. The former two are useless, as is an
ything of the form \code{$e$ \IS{} Object} or \code{$e$ \IS{} \DYNAMIC{}}. User
s should test for a null value directly rather than via type tests. |
| 4337 } |
| 4338 |
| 4339 The is-expression \code{$e$ \IS{}! $T$} is equivalent to \code{!($e$ \IS{} $T$)}
. |
| 4340 |
| 4341 % Add flow dependent types |
| 4342 |
| 4343 \commentary{ |
| 4344 If $T$ is malformed the test always succeeds. This is a consequence of the rule
that malformed types are treated as \DYNAMIC{} |
| 4345 } |
| 4346 %does not denote a type available in the current lexical scope. It is a %compile
-time error % CHANGED |
| 4347 %run-time error |
| 4348 %if $T$ is a parameterized type of the form $G<T_1, \ldots, T_n>$ and $G$ is not
a generic type with $n$ type parameters. |
| 4349 |
| 4350 %Note, that, in checked mode, it is a dynamic type error if a malformed type is
used in a type test as specified in \ref{dynamicTypeSystem}. |
| 4351 |
| 4352 %It is a static warning if $T$ is malformed or malbounded. |
| 4353 %does not denote a type available in the current lexical scope. |
| 4354 |
| 4355 Let $v$ be a local variable or a formal parameter. An is-expression of the form
\code{$v$ \IS{}! $T$} shows that $v$ has type $T$ iff $T$ is a subtype of the
type $S$ of the expression $v$ and both $T \ne \DYNAMIC{}$ and $S \ne \DYNAMIC{
}$. |
| 4356 |
| 4357 The static type of an is-expression is \code{bool}. |
| 4358 %It is a static warning if if $T$ is a parameterized type of the form $G<T_1, \l
dots, T_n>$ and $G$ is not a generic type with $n$ type parameters. |
| 4359 |
| 4360 |
| 4361 |
| 4362 \subsection{ Type Cast} |
| 4363 \label{typeCast} |
| 4364 |
| 4365 The {\em cast expression} ensures that an object is a member of a type. |
| 4366 |
| 4367 \begin{grammar} |
| 4368 {\bf typeCast:} |
| 4369 asOperator type |
| 4370 . |
| 4371 |
| 4372 |
| 4373 {\bf asOperator:} |
| 4374 \AS{} |
| 4375 . |
| 4376 \end{grammar} |
| 4377 |
| 4378 Evaluation of the cast expression \code{$e$ \AS{} $T$} proceeds as follows: |
| 4379 |
| 4380 The expression $e$ is evaluated to a value $v$. Then, if the interface of the cl
ass of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise,
if $v$ is \NULL{}, the cast expression evaluates to $v$. |
| 4381 In all other cases, a \code{CastError} is thrown. |
| 4382 |
| 4383 \commentary{ |
| 4384 If $T$ is malformed the cast always succeeds. This is a consequence of the rule
that malformed types are treated as \DYNAMIC{} |
| 4385 } |
| 4386 |
| 4387 %does not denote a type available in the current lexical scope. It is a %compile
-time error ; CHANGED |
| 4388 %run-time error |
| 4389 %if $T$ is a parameterized type of the form $G<T_1, \ldots, T_n>$ and $G$ is not
a generic type with $n$ type parameters. |
| 4390 |
| 4391 %Note, that, in checked mode, it is a dynamic type error if a malformed type is
used in a type cast as specified in \ref{dynamicTypeSystem}. |
| 4392 |
| 4393 %It is a static warning if $T$ is malformed or malbounded. |
| 4394 %does not denote a type available in the current lexical scope. |
| 4395 The static type of a cast expression \code{$e$ \AS{} $T$} is $T$. |
| 4396 %It is a static warning if if $T$ is a parameterized type of the form $G<T_1, \l
dots, T_n>$ and $G$ is not a generic type with $n$ type parameters. |
| 4397 |
| 4398 |
| 4399 \section{Statements} |
| 4400 \label{statements} |
| 4401 |
| 4402 \begin{grammar} |
| 4403 {\bf statements:} |
| 4404 statement* |
| 4405 . |
| 4406 |
| 4407 |
| 4408 {\bf statement:} |
| 4409 label* nonLabelledStatement |
| 4410 . |
| 4411 |
| 4412 {\bf nonLabelledStatement:}block; |
| 4413 localVariableDeclaration; |
| 4414 forStatement; |
| 4415 whileStatement; |
| 4416 doStatement; |
| 4417 switchStatement; |
| 4418 ifStatement; |
| 4419 rethrowStatement; |
| 4420 tryStatement; |
| 4421 breakStatement; |
| 4422 continueStatement; |
| 4423 returnStatement; |
| 4424 expressionStatement; |
| 4425 assertStatement; |
| 4426 localFunctionDeclaration |
| 4427 . |
| 4428 \end{grammar} |
| 4429 |
| 4430 \subsection{Blocks} |
| 4431 \label{blocks} |
| 4432 |
| 4433 A {\em block statement} supports sequencing of code. |
| 4434 |
| 4435 Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows: |
| 4436 |
| 4437 For $i \in 1 .. n, s_i$ is executed. |
| 4438 |
| 4439 A block statement introduces a new scope, which is nested in the lexically enclo
sing scope in which the block statement appears. |
| 4440 |
| 4441 |
| 4442 |
| 4443 \subsection{Expression Statements} |
| 4444 \label{expressionStatements} |
| 4445 |
| 4446 An {\em expression statement} consists of an expression other than a non-constan
t map literal (\ref{maps}) that has no explicit type arguments. |
| 4447 |
| 4448 \rationale{ |
| 4449 The restriction on maps is designed to resolve an ambiguity in the grammar, whe
n a statement begins with \{. |
| 4450 } |
| 4451 |
| 4452 \begin{grammar} |
| 4453 {\bf expressionStatement:} |
| 4454 expression? `{\escapegrammar ;}' |
| 4455 . |
| 4456 \end{grammar} |
| 4457 |
| 4458 Execution of an expression statement \code{$e$;} proceeds by evaluating $e$. |
| 4459 |
| 4460 It is a compile-time error if a non-constant map literal that has no explicit ty
pe arguments appears in a place where a statement is expected. |
| 4461 |
| 4462 \subsection{Local Variable Declaration} |
| 4463 \label{localVariableDeclaration} |
| 4464 |
| 4465 |
| 4466 A {\em variable declaration statement }declares a new local variable. |
| 4467 |
| 4468 \begin{grammar} |
| 4469 {\bf localVariableDeclaration:} |
| 4470 initializedVariableDeclaration \escapegrammar{';'} |
| 4471 . |
| 4472 \end{grammar} |
| 4473 |
| 4474 Executing a variable declaration statement of one of the forms \VAR{} $v = e;$
, $T$ $v = e; $, \CONST{} $v = e;$, \CONST{} $T$ $v = e;$, \FINAL{} $v = e;$ o
r \FINAL{} $T$ $v = e;$ proceeds as follows: |
| 4475 |
| 4476 The expression $e$ is evaluated to an object $o$. Then, the variable $v$ is set
to $o$. |
| 4477 |
| 4478 A variable declaration statement of the form \VAR{} $v;$ is equivalent to \VAR{
} $v = \NULL{};$. A variable declaration statement of the form $T$ $v;$ is equiv
alent to $T$ $v = \NULL{};$. |
| 4479 |
| 4480 \commentary{ |
| 4481 This holds regardless of the type $T$. For example, \code{int i;} does not cause
\code{i} to be initialized to zero. Instead, \code{i} is initialized to \NULL{}
, just as if we had written \VAR{} \code{i;} or \code{Object i;} or \code{Collec
tion$<$String$>$ i;}. |
| 4482 } |
| 4483 |
| 4484 \rationale{ |
| 4485 To do otherwise would undermine the optionally typed nature of Dart, causing typ
e annotations to modify program behavior. |
| 4486 } |
| 4487 |
| 4488 %A variable declaration statement of one of the forms $T$ $v;$, $T$ $v = e;$, \C
ONST{} $T$ $v = e;$, or \FINAL{} $T$ $v = e;$ causes a new getter named $v$ wit
h static return type $T$ to be added to the innermost enclosing scope at the poi
nt following the variable declaration statement. The result of executing this ge
tter is the value stored in $v$. |
| 4489 |
| 4490 %A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e
;$ or \FINAL{} $v = e;$ causes a new getter named $v$ with static return type
\DYNAMIC{} to be added to the innermost enclosing scope at the point following
the variable declaration statement. The result of executing this getter is the
value stored in $v$. |
| 4491 |
| 4492 %A variable declaration statement of one of the forms $T$ $v;$, or $T$ $v = e;$
causes a new setter named $v=$ with argument type $T$ to be added to the innermo
st enclosing scope at the point following the variable declaration statement. Th
e effect of executing this setter is to store its argument in $v$. |
| 4493 |
| 4494 %A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e
;$ or \FINAL{} $v = e;$ causes a new setter named $v=$ with argument type \D
YNAMIC{} to be added to the innermost enclosing scope at the point following the
variable declaration statement. The effect of executing this setter is to stor
e its argument in $v$. |
| 4495 |
| 4496 %\rationale{ |
| 4497 %The use of getters and setters here is a device to help make the specification
more uniform. Introducing getters and setters for local variables has no perfor
mance consequences, since they can never be overridden, and so can always be opt
imized away. It is not possible to declare a local getter or setter explicitly,
since there is little reason to ever do so. |
| 4498 %} |
| 4499 |
| 4500 %In all of the above cases, it |
| 4501 It is a compile-time error if $e$ refers to the name $v$ or the name $v=$. |
| 4502 |
| 4503 \commentary{ |
| 4504 This rule may seem redundant in light of the scoping rules above. After all: |
| 4505 } |
| 4506 |
| 4507 \begin{dartCode} |
| 4508 f() \{ // a top level function |
| 4509 \VAR{} v = v* 2; |
| 4510 \} |
| 4511 \end{dartCode} |
| 4512 |
| 4513 \commentary{ |
| 4514 is already an error since $v$ is not yet in scope in its own initializer. Howeve
r, consider the more insidious: |
| 4515 } |
| 4516 |
| 4517 \begin{dartCode} |
| 4518 \VAR v = 0; // top level variable |
| 4519 |
| 4520 f() \{ // a top level function |
| 4521 \VAR{} v = v* 2; // compile-time error |
| 4522 \} |
| 4523 \end{dartCode} |
| 4524 |
| 4525 |
| 4526 |
| 4527 |
| 4528 \subsection{Local Function Declaration} |
| 4529 |
| 4530 \label{localFunctionDeclaration} |
| 4531 |
| 4532 A function declaration statement declares a new local function (\ref{functionDec
larations}). |
| 4533 |
| 4534 \begin{grammar} |
| 4535 {\bf localFunctionDeclaration:} |
| 4536 functionSignature functionBody |
| 4537 . |
| 4538 \end{grammar} |
| 4539 |
| 4540 A function declaration statement of one of the forms $id$ $signature$ $\{ statem
ents \}$ or $T$ $id$ $signature$ $\{ statements \}$ causes a new function named
$id$ to be added to the innermost enclosing scope. It is a compile-time error to
reference a local function before its declaration. |
| 4541 |
| 4542 |
| 4543 \commentary{ This implies that local functions can be directly recursive, but no
t mutually recursive. Consider these examples: |
| 4544 } |
| 4545 |
| 4546 \begin{dartCode} |
| 4547 f(x) =$>$ x++; // a top level function |
| 4548 top() \{ // another top level function |
| 4549 f(3); // illegal |
| 4550 f(x) $=>$ x $>$ 0? x*f(x-1): 1; // recursion is legal |
| 4551 g1(x) $=>$ h(x, 1); // error: h is not declared yet |
| 4552 h(x, n) $=>$ x $>$ 1? h(x-1, n*x): n; // again, recursion is fine |
| 4553 g2(x) $=>$ h(x, 1); // legal |
| 4554 |
| 4555 p1(x) $=>$ q(x,x); // illegal |
| 4556 q1(a, b)$ =>$ a $>$ 0 ? p1(a-1): b; // fine |
| 4557 |
| 4558 q2(a, b) $=>$ a $>$ 0 ? p2(a-1): b; // illegal |
| 4559 p1(x) $=>$ q2(x,x); // fine |
| 4560 \} |
| 4561 \end{dartCode} |
| 4562 |
| 4563 \commentary{ |
| 4564 There is no way to write a pair of mutually recursive local functions, because o
ne always has to come before the other is declared. These cases are quite rare,
and can always be managed by defining a pair of variables first, then assigning
them appropriate closures: |
| 4565 } |
| 4566 |
| 4567 \begin{dartCode} |
| 4568 top2() \{ // a top level function |
| 4569 \VAR{} p, q; |
| 4570 p = (x) $=>$ q(x,x); |
| 4571 q = (a, b) $=>$ a $>$ 0 ? p(a-1): b; |
| 4572 |
| 4573 \} |
| 4574 \end{dartCode} |
| 4575 |
| 4576 \rationale{ |
| 4577 The rules for local functions differ slightly from those for local variables in
that a function can be accessed within its declaration but a variable can only
be accessed after its declaration. This is because recursive functions are usefu
l whereas recursively defined variables are almost always errors. It therefore
makes sense to harmonize the rules for local functions with those for functions
in general rather than with the rules for local variables. |
| 4578 } |
| 4579 |
| 4580 % elaborate on function identity and equality, runtime type. Likewsie in functio
n expressions (closures) and declarations |
| 4581 |
| 4582 \subsection{If} |
| 4583 \label{if} |
| 4584 |
| 4585 The {\em if statement} allows for conditional execution of statements. |
| 4586 |
| 4587 \begin{grammar} |
| 4588 {\bf ifStatement:} |
| 4589 \IF{} `(' expression `)' statement ( \ELSE{} statement)? % we could allow
top level expression |
| 4590 . |
| 4591 \end{grammar} |
| 4592 |
| 4593 Execution of an if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ \code{
\ELSE{} } $s_2$ proceeds as follows: |
| 4594 |
| 4595 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. |
| 4596 |
| 4597 |
| 4598 \commentary { |
| 4599 Put another way, \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} } $s_2$ is equiv
alent to |
| 4600 \code {\IF{} (}$b$\code{)}$\{s_1\}$ \code{\ELSE{} } $\{s_2\}$ |
| 4601 } |
| 4602 |
| 4603 \rationale { |
| 4604 The reason for this equivalence is to catch errors such as |
| 4605 } |
| 4606 \begin{dartCode} |
| 4607 \VOID{} main() \{ |
| 4608 \IF{} (somePredicate) |
| 4609 \VAR{} v = 2; |
| 4610 print(v); |
| 4611 \} |
| 4612 \end{dartCode} |
| 4613 |
| 4614 \rationale { |
| 4615 Under reasonable scope rules such code is problematic. If we assume that \code{
v} is declared in the scope of the method \code{main()}, then when \code{somePre
dicate} is false, \code{v} will be uninitialized when accessed. The cleanest ap
proach would be to require a block following the test, rather than an arbitrary
statement. However, this goes against long standing custom, undermining Dart's g
oal of familiarity. Instead, we choose to insert a block, introducing a scope,
around the statement following the predicate (and similarly for \ELSE{} and loo
ps). This will cause both a warning and a runtime error in the case above. Of c
ourse, if there is a declaration of \code{v} in the surrounding scope, programme
rs might still be surprised. We expect tools to highlight cases of shadowing to
help avoid such situations. |
| 4616 } |
| 4617 |
| 4618 It is a static type warning if the type of the expression $b$ may not be assig
ned to \code{bool}. |
| 4619 |
| 4620 If: |
| 4621 \begin{itemize} |
| 4622 \item $b$ shows that a variable $v$ has type $T$. |
| 4623 \item $v$ is not potentially mutated in either $b$, $s_1$ or within a closure. |
| 4624 \item If the variable $v$ is accessed by a closure in $s_1$ then the variable $v
$ is not potentially mutated anywhere in the scope of $v$. |
| 4625 \end{itemize} |
| 4626 then the type of $v$ is known to be $T$ in $s_1$. |
| 4627 |
| 4628 An if statement of the form \code {\IF{} (}$b$\code{)}$s_1$ is equivalent to t
he if statement |
| 4629 |
| 4630 \code {\IF{} (}$b$\code{)}$s_1$ \code{\ELSE{} \{\}}. |
| 4631 |
| 4632 |
| 4633 |
| 4634 \subsection{For} |
| 4635 \label{for} |
| 4636 |
| 4637 The {\em for statement} supports iteration. |
| 4638 |
| 4639 \begin{grammar} |
| 4640 {\bf forStatement:} |
| 4641 \FOR{} `(' forLoopParts `)' statement |
| 4642 . |
| 4643 |
| 4644 {\bf forLoopParts:}forInitializerStatement expression? `{\escapegrammar ;}' expr
essionList?; |
| 4645 declaredIdentifier \IN{} expression; |
| 4646 identifier \IN{} expression |
| 4647 . |
| 4648 |
| 4649 {\bf forInitializerStatement:}localVariableDeclaration `{\escapegrammar ;}'; |
| 4650 expression? `{\escapegrammar ;}' |
| 4651 . |
| 4652 \end{grammar} |
| 4653 |
| 4654 The for statement has two forms - the traditional for loop and the for-in state
ment. |
| 4655 |
| 4656 \subsubsection{For Loop} |
| 4657 \label{forLoop} |
| 4658 |
| 4659 |
| 4660 Execution of a for statement of the form \code{ \FOR{} (\VAR{} $v = e_0$ ; $c$
; $e$) $s$} proceeds as follows: |
| 4661 |
| 4662 If $c$ is empty then let $c^\prime$ be \TRUE{} otherwise let $c^\prime$ be $c$. |
| 4663 |
| 4664 First the variable declaration statement \VAR{} $v = e_0$ is executed. Then: |
| 4665 \begin{enumerate} |
| 4666 \item |
| 4667 \label{beginFor} |
| 4668 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}. |
| 4669 \item |
| 4670 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 |
| 4671 \ref{beginIteration}. |
| 4672 \item |
| 4673 \label{beginIteration} |
| 4674 The statement $[v^\prime/v]\{s\}$ is executed. |
| 4675 \item |
| 4676 \label{allocateFreshVar} |
| 4677 Let $v^{\prime\prime}$ be a fresh variable. $v^{\prime\prime}$ is bound to the
value of $v^\prime$. |
| 4678 \item |
| 4679 The expression $[v^{\prime\prime}/v]e$ is evaluated, and the process recurses at
step |
| 4680 \ref{beginFor}. |
| 4681 \end{enumerate} |
| 4682 |
| 4683 \rationale{ |
| 4684 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. |
| 4685 |
| 4686 Instead, each iteration has its own distinct variable. The first iteration uses
the variable created by the initial declaration. The expression executed at the
end of each iteration uses a fresh variable $v^{\prime\prime}$, bound to the va
lue of the current iteration variable, and then modifies $v^{\prime\prime}$ as r
equired for the next iteration. |
| 4687 } |
| 4688 |
| 4689 |
| 4690 |
| 4691 %A for statement of the form \code{ \FOR{} ($d$ ; $c$; $e$) $s$} is equivalent t
o the the following code: |
| 4692 |
| 4693 %\code{ |
| 4694 %\{$d$; |
| 4695 %\WHILE{} ($c$) \{ |
| 4696 % \{$s$\} |
| 4697 % $e$; |
| 4698 %\}\} |
| 4699 %} |
| 4700 |
| 4701 %If $c$ is empty, it is interpreted as \TRUE{}. |
| 4702 |
| 4703 \subsubsection{For-in} |
| 4704 \label{for-in} |
| 4705 |
| 4706 A for statement of the form \code{ \FOR{} ($varOrType?$ id \IN{} $e$) $s$} is eq
uivalent to the following code: |
| 4707 |
| 4708 \begin{dartCode} |
| 4709 var n0 = $e$.iterator; |
| 4710 \WHILE{} (n0.moveNext()) \{ |
| 4711 $varOrType?$ id = n0.current; |
| 4712 $s$ |
| 4713 \} |
| 4714 \end{dartCode} |
| 4715 where \code{n0} is an identifier that does not occur anywhere in the program. |
| 4716 |
| 4717 \subsection{While} |
| 4718 \label{while} |
| 4719 |
| 4720 The while statement supports conditional iteration, where the condition is evalu
ated prior to the loop. |
| 4721 |
| 4722 \begin{grammar} |
| 4723 {\bf whileStatement:} |
| 4724 \WHILE{} `(' expression `)' statement % could do top level here, and in f
or |
| 4725 . |
| 4726 \end{grammar} |
| 4727 |
| 4728 Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds
as follows: |
| 4729 |
| 4730 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. |
| 4731 |
| 4732 It is a static type warning if the type of $e$ may not be assigned to \code{bool
}. |
| 4733 |
| 4734 |
| 4735 \subsection{Do} |
| 4736 \label{do} |
| 4737 |
| 4738 The do statement supports conditional iteration, where the condition is evaluate
d after the loop. |
| 4739 |
| 4740 \begin{grammar} |
| 4741 {\bf doStatement:} |
| 4742 \DO{} statement \WHILE{} `(' expression `)' `{\escapegrammar ;}'% could do t
op level here |
| 4743 . |
| 4744 \end{grammar} |
| 4745 |
| 4746 |
| 4747 Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceed
s as follows: |
| 4748 |
| 4749 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.
|
| 4750 |
| 4751 It is a static type warning if the type of $e$ may not be assigned to \code{bool
}. |
| 4752 |
| 4753 \subsection{Switch} |
| 4754 \label{switch} |
| 4755 |
| 4756 The {\em switch statement} supports dispatching control among a large number of
cases. |
| 4757 |
| 4758 \begin{grammar} |
| 4759 {\bf switchStatement:} |
| 4760 \SWITCH{} `(' expression `)' `\{' switchCase* defaultCase? `\}'% could do
top level here and in cases |
| 4761 . |
| 4762 |
| 4763 |
| 4764 {\bf switchCase:} |
| 4765 label* (\CASE{} expression `{\escapegrammar :}') statements |
| 4766 . |
| 4767 |
| 4768 {\bf defaultCase:} |
| 4769 label* \DEFAULT{} `{\escapegrammar :}' statements |
| 4770 . |
| 4771 \end{grammar} |
| 4772 |
| 4773 Given a switch statement of the form \code{\SWITCH{} ($e$) \{ \CASE{} $label_{1
1} \ldots label_{1j_1}$ $e_1: s_1 \ldots$ \CASE{} $label_{n1} \ldots label_{nj_
n}$ $e_n: s_n$ \DEFAULT{}: $s_{n+1}$ \}} or the form \code{\SWITCH{} ($e$) \{ \C
ASE{} $label_{11} \ldots label_{1j_1}$ $e_1: s_1 \ldots$ \CASE{} $label_{n1} \l
dots label_{nj_n}$ $e_n: s_n$ \}}, it is a compile-time error if the expressions
$e_k$ are not compile-time constants for all $k \in 1..n$. It is a compile-ti
me error if the values of the expressions $e_k$ are not all instances of the sam
e class $C$ or of a class that implements \cd{int} or \cd{String}, for all $k \i
n 1..n$. |
| 4774 |
| 4775 \commentary{In other words, all the expressions in the cases evaluate to consta
nts of the exact same user defined class or are of certain known types. Note t
hat the values of the expressions are known at compile-time, and are independent
of any static type annotations. |
| 4776 } |
| 4777 |
| 4778 It is a compile-time error if the class $C$ implements the operator $==$ unless
the value of the expression is a string or integer. |
| 4779 |
| 4780 \rationale{ |
| 4781 The prohibition on user defined equality allows us to implement the switch effi
ciently for user defined types. We could formulate matching in terms of identity
instead with the same efficiency. However, if a type defines an equality operat
or, programmers would find it quite surprising that equal objects did not match. |
| 4782 |
| 4783 } |
| 4784 |
| 4785 \commentary{ |
| 4786 The \SWITCH{} statement should only be used in very limited situations (e.g., i
nterpreters or scanners). |
| 4787 } |
| 4788 |
| 4789 %A switch statement {\SWITCH{} ($e$) \{ $label_{11} \ldots label_{1j_1}$ \CASE{
} $e_1: s_1 \ldots$ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ \}} is
equivalent to switch statement \code{\SWITCH{} ($e$) \{ $label_{11} \ldots label
_{1j_1}$ \CASE{} $e_1: s_1 \ldots$ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e
_n: s_n$ \DEFAULT{}: \}} |
| 4790 |
| 4791 Execution of a switch statement of the form \code{\SWITCH{} ($e$) \{ \CASE{} $la
bel_{11} \ldots label_{1j_1}$ $e_1: s_1 \ldots$ \CASE{} $label_{n1} \ldots labe
l_{nj_n}$ $e_n: s_n$ \DEFAULT{}: $s_{n+1}$ \}} or the form \code{\SWITCH{} ($e$)
\{ \CASE{} $label_{11} \ldots label_{1j_1}$ $e_1: s_1 \ldots$ \CASE{} $label_{
n1} \ldots label_{nj_n}$ $e_n: s_n$ \}} proceeds as follows: |
| 4792 |
| 4793 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$. |
| 4794 |
| 4795 \commentary{Note that if there are no case clauses ($n = 0$), the type of $e$ do
es not matter.} |
| 4796 |
| 4797 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}$. |
| 4798 |
| 4799 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. |
| 4800 |
| 4801 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement \co
de{\SWITCH{} ($e$) \{ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1 \ldots
$ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ \DEFAULT{}: $s_{n+1}$ \}}
proceeds as follows: |
| 4802 |
| 4803 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su
bjected to boolean conversion yielding a value $v$. |
| 4804 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}$. |
| 4805 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. |
| 4806 If execution reaches the point after $s_h$ then a runtime error occurs, unless
$h = n+1$. |
| 4807 |
| 4808 Execution of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement \co
de{\SWITCH{} ($e$) \{ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1 \ldots
$ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$ \}} proceeds as follows: |
| 4809 |
| 4810 The expression \code{$e_k$ == id} is evaluated to an object $o$ which is then su
bjected to boolean conversion yielding a value $v$. |
| 4811 If $v$ is not \TRUE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is execut
ed if it exists. |
| 4812 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. |
| 4813 If execution reaches the point after $s_h$ then a runtime error occurs, unless
$h = n$. |
| 4814 |
| 4815 |
| 4816 \commentary{ |
| 4817 In other words, there is no implicit fall-through between cases. The last case i
n a switch (default or otherwise) can `fall-through' to the end of the statement
. |
| 4818 } |
| 4819 |
| 4820 It is a static warning if the type of $e$ may not be assigned to the type of $e_
k$. It is a static warning if the last statement of the statement sequence $s_k$
is not a \BREAK{}, \CONTINUE{}, \RETURN{} or \THROW{} statement. |
| 4821 |
| 4822 \rationale{ |
| 4823 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)
. |
| 4824 |
| 4825 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.: |
| 4826 } |
| 4827 |
| 4828 \begin{dartCode} |
| 4829 \SWITCH{} (x) \{ |
| 4830 \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN{};\} \FINALLY{} \{ $\ldots$ \RETURN{};\} |
| 4831 \} |
| 4832 \end{dartCode} |
| 4833 |
| 4834 \rationale{ |
| 4835 Very elaborate code in a case clause is probably bad style in any case, and su
ch code can always be refactored. |
| 4836 } |
| 4837 |
| 4838 |
| 4839 \subsection{ Rethrow} |
| 4840 \label{rethrow} |
| 4841 |
| 4842 |
| 4843 The {\em rethrow statement} is used to re-raise an exception. |
| 4844 |
| 4845 \begin{grammar} |
| 4846 {\bf rethrowStatement:} |
| 4847 \RETHROW{} |
| 4848 . |
| 4849 \end{grammar} |
| 4850 |
| 4851 Execution of a \code{\RETHROW{}} statement proceeds as follows: |
| 4852 Control is transferred to the nearest innermost enclosing exception handler (\re
f{try}). |
| 4853 |
| 4854 \commentary{No change is made to the current exception.} |
| 4855 |
| 4856 It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed wit
hin an on-catch clause. |
| 4857 |
| 4858 %The static type of a rethrow expression is $\bot$. |
| 4859 |
| 4860 |
| 4861 |
| 4862 \subsection{ Try} |
| 4863 \label{try} |
| 4864 |
| 4865 The try statement supports the definition of exception handling code in a struct
ured way. |
| 4866 |
| 4867 \begin{grammar} |
| 4868 {\bf tryStatement:} |
| 4869 \TRY{} block (onPart+ finallyPart? $|$ finallyPart) |
| 4870 . |
| 4871 |
| 4872 {\bf onPart:}catchPart block; |
| 4873 \ON{} type catchPart? block |
| 4874 . |
| 4875 |
| 4876 {\bf catchPart:} |
| 4877 \CATCH{} `(' identifier (`,' identifier)? `)' |
| 4878 . |
| 4879 |
| 4880 {\bf finallyPart:} |
| 4881 \FINALLY{} block |
| 4882 . |
| 4883 \end{grammar} |
| 4884 |
| 4885 A try statement consists of a block statement, followed by at least one of: |
| 4886 \begin{enumerate} |
| 4887 \item |
| 4888 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. |
| 4889 \item |
| 4890 A \FINALLY{} clause, which consists of a block statement. |
| 4891 \end{enumerate} |
| 4892 |
| 4893 \rationale{ |
| 4894 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. |
| 4895 } |
| 4896 |
| 4897 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$. |
| 4898 |
| 4899 \commentary { |
| 4900 It is of course a static warning if $T$ is a malformed type (\ref{staticTypes}). |
| 4901 } |
| 4902 |
| 4903 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.
|
| 4904 |
| 4905 |
| 4906 An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p$) $s$} is equivalent to
an \ON{}-\CATCH{} clause \code{\ON{} Object \CATCH{} ($p$) $s$}. An \ON{}-\CAT
CH{} clause of the form \code{\CATCH{} ($p_1, p_2$) $s$} is equivalent to an \O
N{}-\CATCH{} clause \code{\ON{} Object \CATCH{} ($p_1, p_2$) $s$} |
| 4907 |
| 4908 |
| 4909 %If an explicit type is associated with of $p_2$, it is a static warning if that
type is not \code{Object} or \DYNAMIC{}. |
| 4910 |
| 4911 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 was thrown. |
| 4912 %\begin{enumerate} |
| 4913 %\item Started execution after the currently executing function. |
| 4914 %\item Had not completed execution at the point where the exception caught by th
e currently executing \ON{}-\CATCH{} clause was initially thrown. |
| 4915 %\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.} |
| 4916 %\end{enumerate} |
| 4917 |
| 4918 \commentary{ |
| 4919 This implies that no synthetic function activations may be added to the trace, n
or may any source level activations be omitted. |
| 4920 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. |
| 4921 |
| 4922 Nothing is said about how any native function calls may be represented in the tr
ace. |
| 4923 } |
| 4924 |
| 4925 |
| 4926 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 \TH
IS{}, and the position at which the function was executing. |
| 4927 |
| 4928 % Is this controversial? We were thinking of viewing the trace as a List<Invoca
tion>, |
| 4929 % 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. |
| 4930 |
| 4931 \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. } |
| 4932 |
| 4933 % A position can be represented via a Token. If we make that part of the core r
eflection facility, we can state this here. |
| 4934 |
| 4935 \rationale{The definition below is an attempt to characterize exception handlin
g without resorting to a normal/abrupt completion formulation. It has the advant
age that one need not specify abrupt completion behavior for every compound stat
ement. On the other hand, it is new and different and needs more thought. |
| 4936 } |
| 4937 |
| 4938 % so, we need to fix things so that returns in the try still go through the fina
lly clause and so that |
| 4939 % uncaught or rethrown exceptions propagate from the finally clause unless it r
eturns. |
| 4940 |
| 4941 % plan: return transfers control to the enclosing finally clause if it exists an
d erases |
| 4942 % any current stack trace & exception. |
| 4943 % But how to ensure return leaves the finally if it does not throw? special text
? say return |
| 4944 % does the finally and then xfers control ? |
| 4945 |
| 4946 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: |
| 4947 |
| 4948 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. |
| 4949 |
| 4950 |
| 4951 A finally clause \FINALLY{} $s$ defines an exception handler $h$ that executes b
y executing the finally clause. |
| 4952 % If the current exception is defined |
| 4953 |
| 4954 Then, execution resumes at the end of the try statement. |
| 4955 |
| 4956 Execution of an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} $
s$ of a try statement $t$ proceeds as follows: The statement $s$ is executed in
the dynamic scope of the exception handler defined by the finally clause of $t$.
Then, the current exception and active stack trace both become undefined. |
| 4957 |
| 4958 Execution of a \FINALLY{} clause \FINALLY{} $s$ of a try statement proceeds as f
ollows: |
| 4959 |
| 4960 The statement $s$ is executed. Then, if the current exception is defined, contro
l is transferred to the nearest dynamically enclosing exception handler. |
| 4961 |
| 4962 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: |
| 4963 |
| 4964 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. |
| 4965 |
| 4966 \commentary{ |
| 4967 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). |
| 4968 |
| 4969 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
. |
| 4970 |
| 4971 If a matching \ON{}-\CATCH{} was found, it will execute first, and then the \FIN
ALLY{} clause will be executed. |
| 4972 |
| 4973 If an exception is raised 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. |
| 4974 |
| 4975 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. |
| 4976 } |
| 4977 |
| 4978 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{} $\{\}$;}. |
| 4979 |
| 4980 |
| 4981 \subsection{ Return} |
| 4982 \label{return} |
| 4983 |
| 4984 The {\em return statement} returns a result to the caller of a function. |
| 4985 |
| 4986 \begin{grammar} |
| 4987 {\bf returnStatement:} |
| 4988 \RETURN{} expression? '{\escapegrammar ;}' % could do top level here |
| 4989 . |
| 4990 \end{grammar} |
| 4991 |
| 4992 Executing a return statement |
| 4993 |
| 4994 \code{\RETURN{} $e$;} |
| 4995 |
| 4996 first causes evaluation of the expression $e$, producing an object $o$. Next, co
ntrol is transferred to the caller of the current function activation, and the o
bject $o$ is provided to the caller as the result of the function call. |
| 4997 |
| 4998 It is a static type warning if the type of $e$ may not be assigned to the declar
ed return type of the immediately enclosing function. |
| 4999 %It is a static warning if the immediately enclosing function of a return statem
ent of the form \code{\RETURN{} $e$;} is \VOID{}. |
| 5000 |
| 5001 In checked mode, it is a dynamic type error if $o$ is not \NULL{} and the runtim
e type of $o$ is not a subtype of the actual return type (\ref{actualTypeOfADecl
aration}) of the immediately enclosing function. |
| 5002 |
| 5003 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$
;} appears in a generative constructor (\ref{generativeConstructors}). |
| 5004 |
| 5005 \rationale{ |
| 5006 It is quite easy to forget to add the factory prefix for a constructor, accident
ally converting a factory into a generative constructor. The static checker may
detect a type mismatch in some, but not all, of these cases. The rule above help
s catch such errors, which can otherwise be very hard to recognize. There is no
real downside to it, as returning a value from a generative constructor is meani
ngless. |
| 5007 } |
| 5008 |
| 5009 Let $f$ be the function immediately enclosing a return statement of the form \RE
TURN{}; It is a static warning if both of the following conditions hold: |
| 5010 \begin{itemize} |
| 5011 \item $f$ is not a generative constructor. |
| 5012 \item The return type of $f$ may not be assigned to \VOID{}. |
| 5013 \end{itemize} |
| 5014 |
| 5015 \commentary{ |
| 5016 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{}. However, any function that declares a return type must return an expressio
n explicitly. |
| 5017 } |
| 5018 |
| 5019 \rationale{This helps catch situations where users forget to return a value in a
return statement.} |
| 5020 |
| 5021 A return statement of the form \code{\RETURN{};} is executed by executing the s
tatement \code{\RETURN{} \NULL{};} if it occurs inside a method, getter, setter
or factory; otherwise, the return statement necessarily occurs inside a generat
ive constructor, in which case it is executed by executing \code{\RETURN{} \THI
S{};}. |
| 5022 |
| 5023 \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{};} |
| 5024 %in a \VOID{} function; neither is it illegal |
| 5025 in a generative constructor. The rules relate only to the specific syntactic for
m \code{\RETURN{} $e$;}. |
| 5026 } |
| 5027 |
| 5028 |
| 5029 \rationale{ |
| 5030 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. |
| 5031 |
| 5032 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. |
| 5033 } |
| 5034 |
| 5035 It is a static warning if a function contains both one or more return statements
of the form \code{\RETURN;} and one or more return statements of the form \code
{\RETURN{} $e$;}. |
| 5036 |
| 5037 |
| 5038 \subsection{ Labels} |
| 5039 \label{labels} |
| 5040 |
| 5041 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$. |
| 5042 |
| 5043 \rationale{The sole role of labels is to provide targets for the break (\ref{bre
ak}) and continue (\ref{continue}) statements.} |
| 5044 |
| 5045 %\Q{Are labels in a separate namespace? Bug 49774299} |
| 5046 |
| 5047 \begin{grammar} |
| 5048 {\bf label:} |
| 5049 identifier '{\escapegrammar :}' |
| 5050 . |
| 5051 \end{grammar} |
| 5052 |
| 5053 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. |
| 5054 |
| 5055 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$. |
| 5056 |
| 5057 \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. |
| 5058 } |
| 5059 |
| 5060 |
| 5061 \subsection{ Break} |
| 5062 \label{break} |
| 5063 |
| 5064 The {\em break statement} consists of the reserved word \BREAK{} and an optional
label (\ref{labels}). |
| 5065 |
| 5066 \begin{grammar} |
| 5067 {\bf breakStatement:} |
| 5068 \BREAK{} identifier? '{\escapegrammar ;}' |
| 5069 . |
| 5070 \end{grammar} |
| 5071 |
| 5072 Let $s_b$ be a \BREAK{} statement. If $s_b$ is of the form \code{\BREAK{} $L$;}
, then let $s_E$ be the 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 the inn
ermost \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 su
ch statement $s_E$ exists within the innermost function in which $s_b$ occurs.
Furthermore, let $s_1, \ldots, s_n$ be those \TRY{} statements that are both en
closed in $s_E$ and that enclose $s_b$, and that have a \FINALLY{} clause. Last
ly, 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
terminates $s_E$. |
| 5073 |
| 5074 |
| 5075 \subsection{ Continue} |
| 5076 \label{continue} |
| 5077 |
| 5078 The {\em continue statement} consists of the reserved word \CONTINUE{} and an op
tional label (\ref{labels}). |
| 5079 |
| 5080 \begin{grammar} |
| 5081 {\bf continueStatement:} |
| 5082 \CONTINUE{} identifier? '{\escapegrammar ;}' |
| 5083 . |
| 5084 \end{grammar} |
| 5085 |
| 5086 Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form \code{\CONTINUE{
} $L$;}, then let $s_E$ be the the innermost labeled \DO{} (\ref{do}), \FOR{} (\
ref{for}) or \WHILE{} (\ref{while}) statement or case clause with label $L$ encl
osing $s_c$. If $s_c$ is of the form \code{\CONTINUE{};} then let $s_E$ be the
the innermost \DO{} (\ref{do}), \FOR{} (\ref{for}) or \WHILE{} (\ref{while}) st
atement enclosing $s_c$. It is a compile-time error if no such statement or cas
e clause $s_E$ exists within the innermost function in which $s_c$ occurs. Fur
thermore, let $s_1, \ldots, s_n$ be those \TRY{} statements that are both enclos
ed 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$ f
irst executes $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 necessarily a loop and execution resumes after the last statement in the loo
p body. |
| 5087 |
| 5088 \commentary{ |
| 5089 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. |
| 5090 } |
| 5091 |
| 5092 |
| 5093 \subsection{ Assert} |
| 5094 \label{assert} |
| 5095 |
| 5096 An {\em assert statement} is used to disrupt normal execution if a given boolean
condition does not hold. |
| 5097 |
| 5098 \begin{grammar} |
| 5099 {\bf assertStatement:} |
| 5100 assert '(' conditionalExpression ')' '{\escapegrammar ;}' |
| 5101 . |
| 5102 \end{grammar} |
| 5103 |
| 5104 The assert statement has no effect in production mode. In checked mode, executio
n of an assert statement \code{\ASSERT{}($e$);} proceeds as follows: |
| 5105 |
| 5106 The conditional expression $e$ is evaluated to an object $o$. If the class of $o
$ is a subtype of \code{Function} then let $r$ be the result of invoking $o$ wit
h no arguments. Otherwise, let $r$ be $o$. |
| 5107 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. |
| 5108 |
| 5109 %\Q{Might be cleaner to define it as \code{if (!$e$) \{\THROW{} \NEW{} Assertion
Error();\}} (in checked mode only). |
| 5110 %What about an error message as part of the assert?} |
| 5111 |
| 5112 It is a static type warning if the type of $e$ may not be assigned to either \
code{bool} or $() \rightarrow$ \code{bool}. |
| 5113 |
| 5114 \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). Overall, perhaps it could be defined as a fun
ction, and the overhead issue could be viewed as an optimization. |
| 5115 } |
| 5116 |
| 5117 %If a lexically visible declaration named \code{assert} is in scope, an assert s
tatement |
| 5118 %\code{\ASSERT{} (e); } |
| 5119 %is interpreted as an expression statement \code{(assert(e));} . |
| 5120 |
| 5121 %\rationale{ |
| 5122 %Since \ASSERT{} is a built-in identifier, one might define a function or method
with this name. |
| 5123 %It is impossible to distinguish as \ASSERT{} statement from a method invocation
in such a situation. |
| 5124 %One could choose to always interpret such code as an \ASSERT{} statement. Or we
could choose to give priority to any lexically visible user defined function.
The former can cause rather puzzling situations, e.g.,} |
| 5125 |
| 5126 %\begin{dartCode} |
| 5127 % assert(bool b)\{print('My Personal Assertion \$b');\} |
| 5128 |
| 5129 % assert\_puzzler() \{ |
| 5130 % (assert(\TRUE{})); // prints true |
| 5131 % assert(\TRUE{}); // would do nothing |
| 5132 % (assert(\FALSE{})); // prints false |
| 5133 % assert(\FALSE{}); // would throw if asserts enabled, or do nothing otherwise |
| 5134 % \} |
| 5135 |
| 5136 %\end{dartCode} |
| 5137 |
| 5138 %\rationale{therefore, we opt for the second option. Alternately, one could insi
st that assert be a reserved word, which may have an undesirable effect with res
pect to compatibility of Javascript code ported to Dart.} |
| 5139 |
| 5140 \section{Libraries and Scripts} |
| 5141 \label{librariesAndScripts} |
| 5142 |
| 5143 A Dart program consists of one or more libraries, and may be built out of one or
more {\em compilation units}. A compilation unit may be a library or a part (\r
ef{parts}). |
| 5144 |
| 5145 A library consists of (a possibly empty) set of imports, asset of exports, and
a set of top-level declarations. A top-level declaration is either a class (\ref
{classes}), a type alias declaration (\ref{typedef}), a function (\ref{functions
}) or a variable declaration (\ref{variables}). The members of a library $L$ are
those top level declarations given within a $L$. |
| 5146 |
| 5147 \begin{grammar} |
| 5148 {\bf topLevelDefinition:}classDefinition; |
| 5149 % classDefinitionOrInterfaceInjection; |
| 5150 % interfaceDefinitionOrInterfaceInjection; |
| 5151 % mixinApplication; |
| 5152 typeAlias; |
| 5153 \EXTERNAL{}? functionSignature `{\escapegrammar ;}'; |
| 5154 \EXTERNAL{}? getterSignature `{\escapegrammar ;}'; |
| 5155 \EXTERNAL{}? setterSignature `{\escapegrammar ;}'; |
| 5156 functionSignature functionBody; |
| 5157 returnType? getOrSet identifier formalParameterList functionBody; |
| 5158 (\FINAL{} $|$ \CONST{}) type? staticFinalDeclarationList `{\escapegrammar
;}'; |
| 5159 variableDeclaration `{\escapegrammar ;}' |
| 5160 . |
| 5161 |
| 5162 {\bf getOrSet:} \GET{}; |
| 5163 \SET{} |
| 5164 . |
| 5165 |
| 5166 % classDefinitionOrInterfaceInjection: |
| 5167 % classDefinition; |
| 5168 % classInterfaceInjection |
| 5169 % . |
| 5170 |
| 5171 %interfaceDefinitionOrInterfaceInjection: |
| 5172 % interfaceDefinition; |
| 5173 % interfaceInterfaceInjection |
| 5174 % . |
| 5175 |
| 5176 {\bf libraryDefinition:} |
| 5177 % library '\{' libraryBody '\}' |
| 5178 scriptTag? libraryName? importOrExport* partDirective* topLevelDefinition* |
| 5179 . |
| 5180 |
| 5181 {\bf scriptTag:} |
| 5182 `\#!' {\escapegrammar (\~{}NEWLINE)*} NEWLINE |
| 5183 . |
| 5184 |
| 5185 {\bf libraryName:} |
| 5186 metadata \LIBRARY{} identifier (`{\escapegrammar .}' identifier)* `{\escapegr
ammar ;}' |
| 5187 . |
| 5188 |
| 5189 {\bf importOrExport:}libraryImport ; |
| 5190 libraryExport |
| 5191 \end{grammar} |
| 5192 |
| 5193 Libraries may be {\em explicitly named} or {\em implicitly named}. An explicitl
y named library begins with the word \LIBRARY{} (possibly prefaced with any ap
plicable metadata annotations), followed by a qualified identifier that gives th
e name of the library. |
| 5194 |
| 5195 \commentary{ |
| 5196 Technically, each dot and identifier is a separate token and so spaces between
them are acceptable. However, the actual library name is the concatenation of th
e simple identifiers and dots and contains no spaces. |
| 5197 } |
| 5198 |
| 5199 An implicitly named library has the empty string as its name. |
| 5200 |
| 5201 \rationale{ |
| 5202 The name of a library is used to tie it to separately compiled parts of the libr
ary (called parts) and can be used for printing and, more generally, reflection
. The name may be relevant for further language evolution. |
| 5203 } |
| 5204 |
| 5205 \commentary{ |
| 5206 Libraries intended for widespread use should avoid name collisions. Dart's \cod
e{pub} package management system provides a mechanism for doing so. Each pub pa
ckage is guaranteed a unique name, effectively enforcing a global namespace. |
| 5207 } |
| 5208 |
| 5209 A library may optionally begin with a {\em script tag}. Script tags are intende
d for use with scripts (\ref{scripts}). A script tag can be used to identify th
e interpreter of the script to whatever computing environment the script is embe
dded in. The script tag must appear before any whitespace or comments. A script
tag begins with the characters \#! and ends at the end of the line. Any charac
ters that follow \#! in the script tag are ignored by the Dart implementation. |
| 5210 |
| 5211 Libraries are units of privacy. A private declaration declared within a library
$L$ can only be accessed by code within $L$. Any attempt to access a private mem
ber declaration from outside $L$ will cause a method, getter or setter lookup fa
ilure. |
| 5212 |
| 5213 \commentary{Since top level privates are not imported, using the top level priva
tes of another library is never possible. } |
| 5214 |
| 5215 The {\em public namespace} of library $L$ is the mapping that maps the simple na
me of each public top-level member $m$ of $L$ to $m$. |
| 5216 The scope of a library $L$ consists of the names introduced by all top-level dec
larations declared in $L$, and the names added by $L$'s imports (\ref{imports}). |
| 5217 |
| 5218 |
| 5219 \subsection{Imports} |
| 5220 \label{imports} |
| 5221 |
| 5222 An {\em import} specifies a library to be used in the scope of another library. |
| 5223 \begin{grammar} |
| 5224 {\bf libraryImport:} |
| 5225 metadata \IMPORT{} uri (\AS{} identifier)? combinator* `{\escapegrammar ;}' |
| 5226 . |
| 5227 |
| 5228 {\bf combinator:}\SHOW{} identifierList; |
| 5229 \HIDE{} identifierList |
| 5230 . |
| 5231 |
| 5232 {\bf identifierList:} |
| 5233 identifier (, identifier)* |
| 5234 \end{grammar} |
| 5235 |
| 5236 |
| 5237 An import specifies a URI $x$ where the declaration of an imported library is to
be found. It is a compile-time error if the specified URI does not refer to a
library declaration. The interpretation of URIs is described in section \ref{ur
is} below. |
| 5238 |
| 5239 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. |
| 5240 |
| 5241 An import directive $I$ may optionally include: |
| 5242 \begin{itemize} |
| 5243 \item A prefix clause of the form \AS{} \code{Id} used to prefix names imported
by $I$. |
| 5244 \item Namespace combinator clauses used to restrict the set of names imported by
$I$. Currently, two namespace combinators are supported: \HIDE{} and \SHOW{}. |
| 5245 \end{itemize} |
| 5246 |
| 5247 Let $I$ be an import directive that refers to a URI via the string $s_1$. Evalua
tion of $I$ proceeds as follows: |
| 5248 |
| 5249 First, |
| 5250 |
| 5251 \begin{itemize} |
| 5252 \item |
| 5253 If the URI that is the value of $s_1$ has not yet been accessed by an import or
export (\ref{exports}) directive in the current isolate then the contents of t
he URI are compiled to yield a library $B$. \commentary{Because libraries may h
ave mutually recursive imports, care must be taken to avoid an infinite regress. |
| 5254 } |
| 5255 \item Otherwise, the contents of the URI denoted by $s_1$ have been compiled int
o a library $B$ within the current isolate. |
| 5256 \end{itemize} |
| 5257 |
| 5258 |
| 5259 Let $NS_0$ be the exported namespace (\ref{exports}) of $B$. Then, for each comb
inator clause $C_i, i \in 1..n$ in $I$: |
| 5260 \begin{itemize} |
| 5261 \item If $C_i$ is of the form |
| 5262 |
| 5263 \code{\SHOW{} $id_1, \ldots, id_k$} |
| 5264 |
| 5265 then let $NS_i = \SHOW{}([id_1, \ldots, id_k], NS_{i-1}$) |
| 5266 |
| 5267 where $show(l,n)$ takes a list of identifiers $l$ and a namespace $n$, and produ
ces a namespace that maps each name in $l$ to the same element that $n$ does. Fu
rthermore, for each name $x$ in $l$, if $n$ defines the name $x=$ then the new
namespace maps $x=$ to the same element that $n$ does. Otherwise the resulting m
apping is undefined. |
| 5268 |
| 5269 \item If $C_i$ is of the form |
| 5270 |
| 5271 \code{\HIDE{} $id_1, \ldots, id_k$} |
| 5272 |
| 5273 then let $NS_i = \HIDE{}([id_1, \ldots, id_k], NS_{i-1}$) |
| 5274 |
| 5275 where $hide(l, n)$ takes a list of identfiers $l$ and a namespace $n$, and produ
ces a namespace that is identical to $n$ except that for each name $k$ in $l$, $
k$ and $k=$ are undefined. |
| 5276 \end{itemize} |
| 5277 |
| 5278 Next, if $I$ includes a prefix clause of the form \AS{} $p$, let $NS = prefix(p
, NS_n)$ where $prefix(id, n)$, takes an identifier $id$ and produces a namespac
e that has, for each entry mapping key $k$ to declaration $d$ in $n$, an entry
mapping $id.k$ to $d$. Otherwise, let $NS = NS_n$. |
| 5279 It is a compile-time error if the current library declares a top-level member na
med $p$. |
| 5280 |
| 5281 Then, for each entry mapping key $k$ to declaration $d$ in $NS$, $d$ is made av
ailable in the top level scope of $L$ under the name $k$ unless either: |
| 5282 \begin{itemize} |
| 5283 \item |
| 5284 a top-level declaration with the name $k$ exists in $L$, OR |
| 5285 \item a prefix clause of the form \AS{} $k$ is used in $L$. |
| 5286 \end{itemize} |
| 5287 |
| 5288 \rationale{The greatly increases the chance that a member can be added to a libr
ary without breaking its importers.} |
| 5289 |
| 5290 If a name $N$ is referenced by a library $L$ and $N$ would be introduced into th
e top level scope $L$ by an import from a library whose name begins with \code{d
art:} and an import from a library whose name does not begin with \code{dart:}: |
| 5291 \begin{itemize} |
| 5292 \item The import from \code{dart:} is implicitly extended by a \code{\HIDE{} $N$
} clause. |
| 5293 \item A static warning is issued. |
| 5294 \end{itemize} |
| 5295 |
| 5296 \rationale { |
| 5297 Whereas normal conflicts are resolved at deployment time, the functionality of \
code{dart:} libraries is injected into an application at run time, and may vary
over time as browsers are upgraded. Thus, conflicts with \code{dart:} libraries
can arise at runtime, outside the developerÕs control. To avoid breaking deploy
ed applications in this way, conflicts with the \code{dart:} libraries are treat
ed specially. |
| 5298 |
| 5299 It is recommended that tools that deploy Dart code produce output in which all i
mports use show clauses to ensure that additions to the namespace of a library n
ever impact deployed code. |
| 5300 } |
| 5301 |
| 5302 If a name $N$ is referenced by a library $L$ and $N$ is introduced into the to
p level scope $L$ by more than one import, and not all the imports denote the sa
me declaration, then: |
| 5303 \begin{itemize} |
| 5304 \item A static warning occurs. |
| 5305 \item If $N$ is referenced as a function, getter or setter, a \code{NoSuchMethod
Error} is raised. |
| 5306 \item If $N$ is referenced as a type, it is treated as a malformed type. |
| 5307 |
| 5308 \end{itemize} |
| 5309 |
| 5310 We say that the namespace $NS$ {\em has been imported into} $L$. |
| 5311 |
| 5312 \commentary{ |
| 5313 It is neither an error nor a warning if $N$ is introduced by two or more import
s but never referred to. |
| 5314 } |
| 5315 |
| 5316 \rationale{ |
| 5317 The policy above makes libraries more robust in the face of additions made to th
eir imports. |
| 5318 |
| 5319 A clear distinction needs to be made between this approach, and seemingly simila
r policies with respect to classes or interfaces. The use of a class or interfa
ce, and of its members, is separate from its declaration. The usage and declarat
ion may occur in widely separated places in the code, and may in fact be authore
d by different people or organizations. It is important that errors are given a
t the offending declaration so that the party that receives the error can respon
d to it a meaningful way. |
| 5320 |
| 5321 In contrast a library comprises both imports and their usage; the library is und
er the control of a single party and so any problem stemming from the import can
be resolved even if it is reported at the use site. |
| 5322 |
| 5323 %On a related note, the provenance of the conflicting elements is not considered
. An element that is imported via distinct paths may conflict with itself. This
avoids variants of the well known "diamond" problem. |
| 5324 } |
| 5325 |
| 5326 It is a static warning to import two different libraries with the same name. |
| 5327 |
| 5328 \commentary{ |
| 5329 A widely disseminated library should be given a name that will not conflict with
other such libraries. The preferred mechanism for this is using pub, the Dart p
ackage manager, which provides a global namespace for libraries, and conventions
that leverage that namespace. |
| 5330 } |
| 5331 |
| 5332 \commentary{Note that no errors or warnings are given if one hides or shows a na
me that is not in a namespace.} |
| 5333 \rationale{ |
| 5334 This prevents situations where removing a name from a library would cause breaka
ge of a client library. |
| 5335 } |
| 5336 |
| 5337 The dart core library \code{dart:core} is implicitly imported into every dart li
brary other than itself via an import clause of the form |
| 5338 |
| 5339 \code{\IMPORT{} `dart:core';} |
| 5340 |
| 5341 unless the importing library explicitly imports \code{dart:core}. |
| 5342 |
| 5343 \commentary{ |
| 5344 Any import of \code{dart:core}, even if restricted via \SHOW{}, \HIDE{} or \AS{}
, preempts the automatic import. |
| 5345 } |
| 5346 |
| 5347 \rationale{ |
| 5348 It would be nice if there was nothing special about \code{dart:core}. However, i
ts use is pervasive, which leads to the decision to import it automatically. Ho
wever, some library $L$ may wish to define entities with names used by \code{da
rt:core} (which it can easily do, as the names declared by a library take preced
ence). Other libraries may wish to use $L$ and may want to use members of $L$ th
at conflict with the core library without having to use a prefix and without enc
ountering warnings. The above rule makes this possible, essentially canceling \c
ode{dart:core}'s special treatment by means of yet another special rule. |
| 5349 } |
| 5350 |
| 5351 \subsection{Exports} |
| 5352 \label{exports} |
| 5353 |
| 5354 A library $L$ exports a namespace (\ref{scoping}), meaning that the declarations
in the namespace are made available to other libraries if they choose to import
$L$ (\ref{imports}). The namespace that $L$ exports is known as its {\em expor
ted namespace}. |
| 5355 |
| 5356 \begin{grammar} |
| 5357 {\bf libraryExport:} |
| 5358 metadata \EXPORT{} uri combinator* `{\escapegrammar ;}' |
| 5359 . |
| 5360 \end{grammar} |
| 5361 |
| 5362 An export specifies a URI $x$ where the declaration of an exported library is t
o be found. It is a compile-time error if the specified URI does not refer to
a library declaration. |
| 5363 |
| 5364 We say that a name {\em is exported by a library} (or equivalently, that a libra
ry {\em exports a name}) if the name is in the library`s exported namespace. We
say that a declaration {\em is exported by a library} (or equivalently, that a l
ibrary {\em exports a declaration}) if the declaration is in the library`s expor
ted namespace. |
| 5365 |
| 5366 A library always exports all names and all declarations in its public namespace.
In addition, a library may choose to re-export additional libraries via {\em ex
port directives}, often referred to simply as {\em exports}. |
| 5367 |
| 5368 Let $E$ be an export directive that refers to a URI via the string $s_1$. Evalua
tion of $E$ proceeds as follows: |
| 5369 |
| 5370 First, |
| 5371 |
| 5372 \begin{itemize} |
| 5373 \item |
| 5374 If the URI that is the value of $s_1$ has not yet been accessed by an import or
export directive in the current isolate then the contents of the URI are comp
iled to yield a library $B$. |
| 5375 \item Otherwise, the contents of the URI denoted by $s_1$ have been compiled int
o a library $B$ within the current isolate. |
| 5376 \end{itemize} |
| 5377 |
| 5378 |
| 5379 Let $NS_0$ be the exported namespace of $B$. Then, for each combinator clause $C
_i, i \in 1..n$ in $E$: |
| 5380 \begin{itemize} |
| 5381 \item If $C_i$ is of the form \code{\SHOW{} $id_1, \ldots, id_k$} then let |
| 5382 |
| 5383 $NS_i = \SHOW{}([id_1, \ldots, id_k], NS_{i-1}$). |
| 5384 \item If $C_i$ is of the form \code{\HIDE{} $id_1, \ldots, id_k$} |
| 5385 |
| 5386 then let $NS_i = \HIDE{}([id_1, \ldots, id_k], NS_{i-1}$). |
| 5387 \end{itemize} |
| 5388 |
| 5389 For each |
| 5390 entry mapping key $k$ to declaration $d$ in $NS_n$ an entry mapping $k$ to $d$ i
s added to the exported namespace of $L$ unless a top-level declaration with th
e name $k$ exists in $L$. We say that $L$ {\em re-exports library } $B$, and al
so that $L$ {\em re-exports namespace } $NS_n$. When no confusion can arise, we
may simply state that $L$ {\em re-exports }$B$, or that $L$ {\em re-exports }$NS
_n$. |
| 5391 |
| 5392 It is a compile-time error if a name $N$ is re-exported by a library $L$ and $N$
is introduced into the export namespace of $L$ by more than one export, unless
each all exports refer to same declaration for the name $N$. It is a static wa
rning to export two different libraries with the same name. |
| 5393 |
| 5394 |
| 5395 |
| 5396 \subsection{Parts} |
| 5397 \label{parts} |
| 5398 |
| 5399 A library may be divided into {\em parts}, each of which can be stored in a sepa
rate location. A library identifies its parts by listing them via \PART{} direct
ives. |
| 5400 |
| 5401 A {\em part directive} specifies a URI where a Dart compilation unit that should
be incorporated into the current library may be found. |
| 5402 |
| 5403 \begin{grammar} |
| 5404 {\bf partDirective:} |
| 5405 metadata \PART{} uri '{\escapegrammar ;}' |
| 5406 . |
| 5407 |
| 5408 {\bf partHeader:} |
| 5409 metadata \PART{} \OF{} identifier (`{\escapegrammar .}' identifier)* `{\es
capegrammar ;}' |
| 5410 . |
| 5411 {\bf partDeclaration:} |
| 5412 partHeader topLevelDefinition* EOF |
| 5413 . |
| 5414 \end{grammar} |
| 5415 |
| 5416 A {\em part header} begins with \PART{} \OF{} followed by the name of the libr
ary the part belongs to. A part declaration consists of a part header followed
by a sequence of top-level declarations. |
| 5417 |
| 5418 Compiling a part directive of the form \code{\PART{} $s$;} causes the Dart syste
m to attempt to compile the contents of the URI that is the value of $s$. The to
p-level declarations at that URI are then compiled by the Dart compiler in the s
cope of the current library. It is a compile-time error if the contents of the U
RI are not a valid part declaration. It is a static warning if the referenced pa
rt declaration $p$ names a library other than the current library as the library
to which $p$ belongs. |
| 5419 |
| 5420 \subsection{Scripts} |
| 5421 \label{scripts} |
| 5422 |
| 5423 A {\em script} is a library with a top-level function \code{main()}. |
| 5424 A script $S$ may be executed as follows: |
| 5425 |
| 5426 First, $S$ is compiled as a library as specified above. Then, the top-level func
tion \code{main()} that is in scope in $S$ is invoked with no arguments. It is a
run time error if $S$ does not declare or import a top-level function \code{mai
n()}. |
| 5427 |
| 5428 \rationale{ |
| 5429 The names of scripts are optional, in the interests of interactive, informal use
. However, any script of long term value should be given a name as a matter of g
ood practice. |
| 5430 } |
| 5431 |
| 5432 \subsection{URIs} |
| 5433 \label{uris} |
| 5434 |
| 5435 URIs are specified by means of string literals: |
| 5436 |
| 5437 \begin{grammar} |
| 5438 {\bf uri:} |
| 5439 stringLiteral |
| 5440 . |
| 5441 \end{grammar} |
| 5442 |
| 5443 It is a compile-time error if the string literal $x$ that describes a URI is no
t a compile-time constant, or if $x$ involves string interpolation. |
| 5444 |
| 5445 This specification does not discuss the interpretation of URIs, with the followi
ng exceptions. |
| 5446 |
| 5447 \rationale{ |
| 5448 The interpretation of URIs is mostly left to the surrounding computing environm
ent. For example, if Dart is running in a web browser, that browser will likely
interpret some URIs. While it might seem attractive to specify, say, that URIs a
re interpreted with respect to a standard such as IETF RFC 3986, in practice thi
s will usually depend on the browser and cannot be relied upon. |
| 5449 } |
| 5450 |
| 5451 A URI of the form \code{dart:$s$} is interpreted as a reference to a library $s$
that is part of the Dart implementation. |
| 5452 |
| 5453 A URI of the form \code{package:$s$} is interpreted as a URI of the form \code{p
ackages/s} relative to an implementation specified location. |
| 5454 |
| 5455 \commentary{ |
| 5456 This location will often be the location of the root library presented to the Da
rt compiler. However, implementations may supply means to override or replace th
is choice. |
| 5457 } |
| 5458 |
| 5459 \rationale{ |
| 5460 The intent is that, during development, Dart programmers can rely on a package m
anager to find elements of their program. Such package managers may provide a di
rectory structure starting at a local directory \code{packages} where they place
the required dart code (or links thereto). |
| 5461 } |
| 5462 |
| 5463 Otherwise, any relative URI is interpreted as relative to the the location of th
e current library. All further interpretation of URIs is implementation dependen
t. |
| 5464 |
| 5465 \commentary{This means it is dependent on the embedder.} |
| 5466 |
| 5467 |
| 5468 \section{Types} |
| 5469 \label{types} |
| 5470 |
| 5471 Dart supports optional typing based on interface types. |
| 5472 |
| 5473 \rationale{The type system is unsound, due to the covariance of generic types. T
his is a deliberate choice (and undoubtedly controversial). Experience has show
n that sound type rules for generics fly in the face of programmer intuition. It
is easy for tools to provide a sound type analysis if they choose, which may be
useful for tasks like refactoring. |
| 5474 } |
| 5475 |
| 5476 \subsection{Static Types} |
| 5477 \label{staticTypes} |
| 5478 |
| 5479 Static type annotations are used in variable declarations (\ref{variables}) (inc
luding formal parameters (\ref{formalParameters})), in the return types of funct
ions (\ref{functions}) and in the bounds of type variables. Static type annotat
ions are used during static checking and when running programs in checked mode.
They have no effect whatsoever in production mode. |
| 5480 |
| 5481 \begin{grammar} |
| 5482 {\bf type:} |
| 5483 typeName typeArguments? |
| 5484 . |
| 5485 |
| 5486 {\bf typeName:} |
| 5487 qualified |
| 5488 . |
| 5489 |
| 5490 {\bf typeArguments:} |
| 5491 '<' typeList '>' |
| 5492 . |
| 5493 |
| 5494 {\bf typeList:} |
| 5495 type (',' type)* |
| 5496 . |
| 5497 \end{grammar} |
| 5498 |
| 5499 A Dart implementation must provide a static checker that detects and reports exa
ctly those situations this specification identifies as static warnings and only
those situations. However: |
| 5500 \begin{itemize} |
| 5501 \item Running the static checker on a program $P$ is not required for compiling
and running $P$. |
| 5502 \item Running the static checker on a program $P$ must not prevent successful co
mpilation of $P$ nor may it prevent the execution of $P$, regardless of whether
any static warnings occur. |
| 5503 \end{itemize} |
| 5504 |
| 5505 \commentary{Nothing precludes additional tools that implement alternative static
analyses (e.g., interpreting the existing type annotations in a sound manner su
ch as either non-variant generics, or inferring declaration based variance from
the actual declarations). However, using these tools must not preclude successfu
l compilation and execution of Dart code. |
| 5506 } |
| 5507 |
| 5508 %\Q{Should we do something with respect to non-nullable types?} |
| 5509 |
| 5510 A type $T$ is {\em malformed} iff: |
| 5511 \begin{itemize} |
| 5512 \item $T$ has the form $id$ or the form $prefix.id$, and in the enclosing lexica
l scope, the name $id$ (respectively $prefix.id$) does not denote a type. |
| 5513 \item $T$ denotes a type variable in the enclosing lexical scope, but occurs in
the signature or body of a static member. |
| 5514 \item $T$ is a parameterized type of the form $G<S_1, \ldots , S_n>$, and $G$ i
s malformed. |
| 5515 \item $T$ denotes declarations that were imported from multiple imports clauses. |
| 5516 %Either $G$ or $S_i, i \in 1.. n$ are malformed. |
| 5517 % \item $G$ is not a generic type with $n$ type parameters. |
| 5518 % \item Let $T_i$ be the type parameters of $G$ (if any) and let $B_i$ be the b
ound of $T_i, i \in 1.. n$, and $S_i$ is not a subtype of $[S_1, \ldots, S_n/T
_1, \ldots, T_n]B_i, i \in 1.. n$. |
| 5519 % \end{itemize} |
| 5520 \end{itemize} |
| 5521 |
| 5522 Any use of a malformed type gives rise to a static warning. A malformed type i
s then interpreted as \DYNAMIC{} by the static type checker and the runtime. |
| 5523 |
| 5524 \rationale{ |
| 5525 This ensures that the developer is spared a series of cascading warnings as the
malformed type interacts with other types. |
| 5526 } |
| 5527 |
| 5528 \subsubsection{Type Promotion} |
| 5529 \label{typePromotion} |
| 5530 |
| 5531 The static type system ascribes a static type to every expression. In some case
s, the types of local variables and formal parameters may be promoted from their
declared types based on control flow. |
| 5532 |
| 5533 We say that a variable $v$ is known to have type $T$ whenever we allow the type
of $v$ to be promoted. The exact circumstances when type promotion is allowed ar
e given in the relevant sections of the specification (\ref{logicalBooleanExpres
sions}, \ref{conditional} and \ref{if}). |
| 5534 |
| 5535 Type promotion for a variable v is allowed only when we can deduce that such pro
motion is valid based on an analysis of certain boolean expressions. In such cas
es, we say that the boolean expression b shows that v has type T. As a rule, for
all variables v and types T, a boolean expression does not show that v has type
T. Those situations where an expression does show that a variable has a type ar
e mentioned explicitly in the relevant sections of this specification (\ref{type
Test} and \ref{logicalBooleanExpressions}). |
| 5536 |
| 5537 |
| 5538 \subsection{Dynamic Type System} |
| 5539 \label{dynamicTypeSystem} |
| 5540 |
| 5541 A Dart implementation must support execution in both {\em production mode} and {
\em checked mode}. Those dynamic checks specified as occurring specifically in
checked mode must be performed iff the code is executed in checked mode. |
| 5542 |
| 5543 %It is a run-time type error to access an undeclared type outside . |
| 5544 |
| 5545 %It is a dynamic type error if a malformed type is used in a subtype test. |
| 5546 In checked mode, it is a dynamic type error if a malbounded (\ref{parameterized
Types}) |
| 5547 type is used in a subtype test. |
| 5548 |
| 5549 %In production mode, an undeclared type is treated as an instance of type \DYNAM
IC{}. |
| 5550 |
| 5551 \commentary{Consider the following program} |
| 5552 |
| 5553 \begin{dartCode} |
| 5554 \TYPEDEF{} F(bool x); |
| 5555 f(foo x) $=>$ x; |
| 5556 main() \{ |
| 5557 if (f is F) \{ |
| 5558 print("yoyoma"); |
| 5559 \} |
| 5560 \} |
| 5561 \end{dartCode} |
| 5562 |
| 5563 \commentary{ |
| 5564 The type of the formal parameter of $f$ is $foo$, which is undeclared in the lex
ical scope. This will lead to a static type warning. At runtime the program will
print \cd{yoyoma}, because $foo$ is treated as \DYNAMIC{}. |
| 5565 %fail when executing the type test on the first line of $main()$ because it lead
s to a subtype comparison involving a malformed type ($foo$). |
| 5566 |
| 5567 As another example take} |
| 5568 |
| 5569 \begin{dartCode} |
| 5570 \VAR{} i; |
| 5571 i j; // a variable j of type i (supposedly) |
| 5572 main() \{ |
| 5573 j = 'I am not an i'; |
| 5574 \} |
| 5575 \end{dartCode} |
| 5576 |
| 5577 \commentary{ |
| 5578 Since $i$ is not a type, a static warning will be issue at the declaration of $j
$. However, the program can be executed without incident. The undeclared type $
i$ is treated as \DYNAMIC{}, so even in checked mode, the implicit subtype test
at the assignment succeeds. |
| 5579 } |
| 5580 |
| 5581 \rationale{ |
| 5582 We have chosen to treat malformed types as type \DYNAMIC{}. Earlier versions of
this specification did so in some cases but not in others. We found the rules t
o be too complex, and have opted to harmonize the specification. Given that a st
atic warning is issued, there is no need for the runtime to deal with extra comp
lexity by treating malformed types specially. |
| 5583 |
| 5584 |
| 5585 %as is done in production mode. After all, a static warning has already been giv
en. That is a legitimate design option, and it is ultimately a judgement call as
to whether checked mode should be more or less aggressive in dealing with such
a situation. |
| 5586 |
| 5587 %Likewise, we could opt to ignore malformed types entirely in checked mode. |
| 5588 |
| 5589 %For now, we have opted to treat a malformed type as an error type that has no s
ubtypes or supertypes, and which causes a runtime error when tested against any
other type. |
| 5590 } |
| 5591 |
| 5592 \commentary{ |
| 5593 Here is an example involving malbounded types: |
| 5594 } |
| 5595 |
| 5596 \begin{dartCode} |
| 5597 \INTERFACE{} I$<$T \EXTENDS{} num$>$ \{\} |
| 5598 \INTERFACE{} J \{\} |
| 5599 |
| 5600 \CLASS{} A$<$T$>$ \IMPLEMENTS{} J, I$<$T$>$ // type warning: T is not a subtype
of num |
| 5601 \{ ... |
| 5602 \} |
| 5603 \end{dartCode} |
| 5604 |
| 5605 \commentary{Given the declarations above, the following} |
| 5606 |
| 5607 \begin{dartCode} |
| 5608 I x = \NEW{} A$<$String$>$(); |
| 5609 \end{dartCode} |
| 5610 |
| 5611 \commentary{ |
| 5612 will cause a dynamic type error in checked mode, because the assignment requires
a subtype test A$<$String$>$ $<$: I. To show that this holds, we need to show t
hat A$<$String$>$ $<<$ I$<$String$>$, but I$<$String$>$ is a malbounded type, c
ausing the dynamic error. No error is thrown in production mode. Note that |
| 5613 } |
| 5614 |
| 5615 \begin{dartCode} |
| 5616 J x = \NEW{} A$<$String$>$(); |
| 5617 \end{dartCode} |
| 5618 |
| 5619 \commentary{ |
| 5620 does not cause a dynamic error, as there is no need to test against \code{I$<$St
ring$>$} in this case. |
| 5621 Similarly, in production mode |
| 5622 } |
| 5623 |
| 5624 \begin{dartCode} |
| 5625 A x = \NEW{} A$<$String$>$(); |
| 5626 bool b = x is I; |
| 5627 \end{dartCode} |
| 5628 |
| 5629 \commentary{ |
| 5630 \code{b} is bound to true, but in checked mode the second line causes a dynamic
type error. |
| 5631 } |
| 5632 |
| 5633 |
| 5634 |
| 5635 \subsection{Type Declarations} |
| 5636 \label{typeDeclarations} |
| 5637 |
| 5638 \subsubsection{Typedef} |
| 5639 \label{typedef} |
| 5640 |
| 5641 A {\em type alias} declares a name for a type expression. |
| 5642 |
| 5643 |
| 5644 \begin{grammar} |
| 5645 |
| 5646 {\bf typeAlias:} |
| 5647 metadata \TYPEDEF{} typeAliasBody |
| 5648 . |
| 5649 |
| 5650 {\bf typeAliasBody:} |
| 5651 functionTypeAlias |
| 5652 . |
| 5653 |
| 5654 {\bf functionTypeAlias:} |
| 5655 functionPrefix typeParameters? formalParameterList '{\escapegrammar ;}' |
| 5656 . |
| 5657 |
| 5658 {\bf functionPrefix:} |
| 5659 returnType? identifier |
| 5660 . |
| 5661 |
| 5662 \end{grammar} |
| 5663 |
| 5664 The effect of a type alias of the form \code{\TYPEDEF{} $T$ $id (T_1$ $p_1, \l
dots, T_n$ $p_n, [T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k}])$} declared in a
library $L$ is is to introduce the name $id$ into the scope of $L$, bound to th
e function type $(T_1, \ldots, T_n, [T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_{n+k
}]) \rightarrow T$. The effect of a type alias of the form \code{\TYPEDEF{}
$T$ $id (T_1$ $p_1, \ldots, T_n$ $p_n, \{T_{n+1}$ $p_{n+1}, \ldots, T_{n+k}$ $p_
{n+k}\})$} declared in a library $L$ is is to introduce the name $id$ into the s
cope of $L$, bound to the function type $(T_1, \ldots, T_n, \{T_{n+1}$ $p_{n+1},
\ldots, T_{n+k}$ $p_{n+k}\}) \rightarrow T$. . In either case, iff no return t
ype is specified, it is taken to be \DYNAMIC{}. Likewise, if a type annotation i
s omitted on a formal parameter, it is taken to be \DYNAMIC{}. |
| 5665 |
| 5666 It is a compile-time error if any default values are specified in the signature
of a function type alias. |
| 5667 %A typedef may only refer to itself via the bounds of its generic parameters. |
| 5668 Any self reference in a typedef, either directly, or recursively via another ty
pedef, is a compile time error. |
| 5669 %via a chain of references that does not include a class declaration. |
| 5670 |
| 5671 |
| 5672 |
| 5673 \subsection{Interface Types} |
| 5674 \label{interfaceTypes} |
| 5675 |
| 5676 The implicit interface of class $I$ is a direct supertype of the implicit interf
ace of class $J$ iff: |
| 5677 \begin{itemize} |
| 5678 \item |
| 5679 If $I$ is \code{Object}, and $J$ has no \EXTENDS{} clause% and no interface inje
ction declaration has extended $J. |
| 5680 \item |
| 5681 If $I$ is listed in the \EXTENDS{} clause of $J$% or an interface injection decl
aration has extended $J$ with $I$ |
| 5682 . |
| 5683 \item If $I$ is listed in the \IMPLEMENTS{} clause of $J$ |
| 5684 |
| 5685 \item If $I$ is listed in the \WITH{} clause of $J$ |
| 5686 |
| 5687 \item If $J$ is a mixin application (\ref{mixinApplication}) of the mixin of $I$
. |
| 5688 \end{itemize} |
| 5689 |
| 5690 \commentary{ |
| 5691 |
| 5692 |
| 5693 } |
| 5694 |
| 5695 %\Q{Can wacky stuff happen with interface injection, e.g., a direct superinterfa
ce becomes indirect? What about side effects - loading order can affect type rel
ationships. |
| 5696 %} |
| 5697 |
| 5698 A type $T$ is more specific than a type $S$, written $T << S$, if one of the fo
llowing conditions is met: |
| 5699 \begin{itemize} |
| 5700 \item $T$ is $S$. |
| 5701 \item T is $\bot$. |
| 5702 \item S is \DYNAMIC{}. |
| 5703 \item $S$ is a direct supertype of $T$. |
| 5704 \item $T$ is a type parameter and $S$ is the upper bound of $T$. |
| 5705 \item $T$ is a type parameter and $S$ is \cd{Object}. |
| 5706 \item $T$ is of the form $I<T_1, \ldots, T_n>$ and $S$ is of the form $I<S_1, \l
dots, S_n>$ and: |
| 5707 $T_i << S_i, 1 \le i \le n$ |
| 5708 \item $T << U$ and $U << S$. |
| 5709 \end{itemize} |
| 5710 |
| 5711 $<<$ is a partial order on types. |
| 5712 $T$ is a subtype of $S$, written $T <: S$, iff $[\bot/\DYNAMIC{}]T << S$. |
| 5713 |
| 5714 \rationale{ |
| 5715 Note that $<:$ is not a partial order on types, it is only binary relation on ty
pes. This is because $<:$ is not transitive. If it was, the subtype rule would h
ave a cycle. For example: |
| 5716 $List <: List<String>$ and $List<int> <: List$, but $List<int>$ is not a subtype
of $List<String>$. |
| 5717 Although $<:$ is not a partial order on types, it does contain a partial order,
namely $<<$. This means that, barring raw types, intuition about classical subty
pe rules does apply. |
| 5718 } |
| 5719 |
| 5720 $S$ is a supertype of $T$, written $S :> T$, iff $T$ is a subtype of $S$. |
| 5721 |
| 5722 \commentary{The supertypes of an interface are its direct supertypes and their s
upertypes. } |
| 5723 |
| 5724 An interface type $T$ may be assigned to a type $S$, written $T \Longleftrighta
rrow S$, iff either $T <: S$ or $S <: T$. |
| 5725 |
| 5726 \rationale{This rule may surprise readers accustomed to conventional typecheckin
g. The intent of the $\Longleftrightarrow$ relation is not to ensure that an ass
ignment is correct. Instead, it aims to only flag assignments that are almost ce
rtain to be erroneous, without precluding assignments that may work. |
| 5727 |
| 5728 For example, assigning a value of static type Object to a variable with static t
ype String, while not guaranteed to be correct, might be fine if the runtime val
ue happens to be a string. |
| 5729 } |
| 5730 |
| 5731 \subsection{Function Types} |
| 5732 \label{functionTypes} |
| 5733 |
| 5734 Function types come in two variants: |
| 5735 \begin{enumerate} |
| 5736 \item |
| 5737 The types of functions that only have positional parameters. These have the gen
eral form $(T_1, \ldots, T_n, [T_{n+1} \ldots, T_{n+k}]) \rightarrow T$. |
| 5738 \item |
| 5739 The types of functions with named parameters. These have the general form $(T_1
, \ldots, T_n, \{T_{x_1}$ $x_1 \ldots, T_{x_k}$ $x_k\}) \rightarrow T$. |
| 5740 \end{enumerate} |
| 5741 |
| 5742 %$(T_1, \ldots T_n) \rightarrow T$ is a subtype of $(S_1, \ldots, S_n, ) \right
arrow S$, if all of the following conditions are met: |
| 5743 %\begin{enumerate} |
| 5744 %\item Either |
| 5745 %\begin{itemize} |
| 5746 %\item $S$ is \VOID{}, Or |
| 5747 %\item $T \Longleftrightarrow S$. |
| 5748 %\end{itemize} |
| 5749 %\item$ \forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. |
| 5750 %\end{enumerate} |
| 5751 |
| 5752 %A function type $(T_1, \ldots T_n, [T_{n+1} \ldots, T_{n+k}]) \rightarrow T$ i
s a subtype of the |
| 5753 % the line below revises the rule to be more liberal |
| 5754 A function type $(T_1, \ldots T_{k}, [T_{k+1} \ldots, T_{n+m}]) \rightarrow T$
is a subtype of the |
| 5755 function type $(S_1, \ldots, S_{k+j}, [S_{k+j+1} \ldots, S_{n}]) \rightarrow S$,
if all of the following conditions are met: |
| 5756 \begin{enumerate} |
| 5757 \item Either |
| 5758 \begin{itemize} |
| 5759 \item $S$ is \VOID{}, Or |
| 5760 \item $T \Longleftrightarrow S$. |
| 5761 \end{itemize} |
| 5762 \item $\forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. |
| 5763 \end{enumerate} |
| 5764 |
| 5765 |
| 5766 A function type $(T_1, \ldots T_n, \{T_{x_1}$ $x_1, \ldots, T_{x_k}$ $x_k\}) \ri
ghtarrow T$ is a subtype of the function type $(S_1, \ldots, S_n, \{S_{y_1}$ $y_
1, \ldots, S_{y_m}$ $y_m\}) \rightarrow S$, if all of the following conditions a
re met: |
| 5767 \begin{enumerate} |
| 5768 \item Either |
| 5769 \begin{itemize} |
| 5770 \item $S$ is \VOID{}, Or |
| 5771 \item $T \Longleftrightarrow S$. |
| 5772 \end{itemize} |
| 5773 \item $\forall i \in 1 .. n, T_i \Longleftrightarrow S_i$. |
| 5774 \item $k \ge m$ and $y_i \in \{x_1, \ldots, x_k\}, i \in 1 .. m$. |
| 5775 %\{x_1, \ldots, x_k\}$ is a superset of $\{y_1, \ldots, y_m\}$. |
| 5776 \item For all $y_i \in \{y_1, \ldots, y_m\}, y_i = x_j \Rightarrow T_j \Longlef
trightarrow S_i$ |
| 5777 \end{enumerate} |
| 5778 |
| 5779 %In addition, a function type $(T_1, \ldots, Tn, [T_{n+1} x_{n+1}, \ldots, T_{n+
k} x_{n+k}]) \rightarrow T$ is a subtype of the function type $(T_1, \ldots, T_n
, T_{n+1} , [T_{n+2} x_{n+2}, \ldots, T_{n+k} x_{n+k}]) \rightarrow T$. |
| 5780 |
| 5781 %\rationale{This second rule is attractive to web developers, who are used to th
is sort of flexibility from Javascript. However, it may be costly to implement e
fficiently.} \Q{Should we do this or not?} |
| 5782 |
| 5783 %We write $(T_1, \ldots, T_n) \rightarrow T$ as a shorthand for the type $(T_1,
\ldots, T_n, []) \rightarrow T$. |
| 5784 |
| 5785 %The rules above need to be sanity checked, but the intent is that we view funct
ions with rest parameters as having type $(T_1, ..., T_n, [\_{Tn+1}[] \_]) \righ
tarrow T$, where \_ is some magical identifier. Then the rules above may cover e
verything. |
| 5786 % This is wrong - from the outside, the type takes an unbounded sequence of type
s, not a list. This can be modeled as $(T_1, \ldots, T_n, [T_{n+1}, \_ \ldots, T
_{n+k} \_]) \rightarrow T$ for some finite $k$. |
| 5787 |
| 5788 In addition, the following subtype rules apply: |
| 5789 |
| 5790 |
| 5791 $(T_1, \ldots, T_n, []) \rightarrow T <: (T_1, \ldots, T_n) \rightarrow T$. |
| 5792 |
| 5793 $(T_1, \ldots, T_n) \rightarrow T <: (T_1, \ldots, T_n, \{\}) \rightarrow T$. |
| 5794 |
| 5795 $(T_1, \ldots, T_n, \{\}) \rightarrow T <: (T_1, \ldots, T_n) \rightarrow T$. |
| 5796 |
| 5797 $(T_1, \ldots, T_n) \rightarrow T <: (T_1, \ldots, T_n, []) \rightarrow T$. |
| 5798 |
| 5799 \rationale{ |
| 5800 The naive reader might conclude that, since it is not legal to declare a functio
n with an empty optional parameter list, these rules are pointless. However, the
y induce useful relationships between function types that declare no optional p
arameters and those that do. |
| 5801 } |
| 5802 |
| 5803 A function type $T$ may be assigned to a function type $S$, written $T \Longlef
trightarrow S$, iff $T <: S$. |
| 5804 |
| 5805 % ensure that Object and dynamic may be assign dot a function type |
| 5806 A function is always an instance of some class that implements the class \code{F
unction} and implements a \CALL{} method with the same signature as the function
. All function types are subtypes of \code{Function}. |
| 5807 If a type $I$ includes an instance method named \CALL{}, and the type of \CALL{}
is the function type $F$, then $I$ is considered to be a subtype of $F$. It is
a static warning if a concrete class implements \cd{Function} and does not have
a concrete method named \CALL{}. |
| 5808 |
| 5809 |
| 5810 |
| 5811 |
| 5812 %\commentary{Need to specify how a function values dynamic type is derived from
its static signature.} |
| 5813 |
| 5814 \subsection{Type \DYNAMIC{}} |
| 5815 \label{typeDynamic} |
| 5816 |
| 5817 The type \DYNAMIC{} denotes the unknown type. |
| 5818 |
| 5819 If no static type annotation has been provided the type system assumes the decla
ration has the unknown type. If a generic type is used but type arguments are no
t provided, then the type arguments default to the unknown type. |
| 5820 |
| 5821 \commentary{This means that given a generic declaration $G<T_1, \ldots, T_n>$, t
he type $G$ is equivalent to $G< \DYNAMIC{}, \ldots, \DYNAMIC{}>$. |
| 5822 } |
| 5823 |
| 5824 Type \DYNAMIC{} has methods for every possible identifier and arity, with every
possible combination of named parameters. These methods all have \DYNAMIC{} as
their return type, and their formal parameters all have type \DYNAMIC{}. |
| 5825 Type \DYNAMIC{} has properties for every possible identifier. These properties
all have type \DYNAMIC{}. |
| 5826 |
| 5827 \rationale{From a usability perspective, we want to ensure that the checker does
not issue errors everywhere an unknown type is used. The definitions above ensu
re that no secondary errors are reported when accessing an unknown type. |
| 5828 |
| 5829 The current rules say that missing type arguments are treated as if they were th
e type \DYNAMIC{}. An alternative is to consider them as meaning \code{Object}
. This would lead to earlier error detection in checked mode, and more aggressi
ve errors during static typechecking. For example: |
| 5830 |
| 5831 (1) \code{typedAPI(G\lt{String}\gt g)\{...\}} |
| 5832 |
| 5833 |
| 5834 (2) \code{typedAPI(new G()); } |
| 5835 |
| 5836 |
| 5837 Under the alternative rules, (2) would cause a runtime error in checked mode. Th
is seems desirable from the perspective of error localization. However, when a d
ynamic error is raised at (2), the only way to keep running is rewriting (2) int
o |
| 5838 |
| 5839 (3) \code{typedAPI(new G\lt{String}\gt());} |
| 5840 |
| 5841 This forces users to write type information in their client code just because th
ey are calling a typed API. We do not want to impose this on Dart programmers,
some of which may be blissfully unaware of types in general, and genericity in p
articular. |
| 5842 |
| 5843 What of static checking? Surely we would want to flag (2) when users have explic
itly asked for static typechecking? Yes, but the reality is that the Dart static
checker is likely to be running in the background by default. Engineering teams
typically desire a ``clean build'' free of warnings and so the checker is desig
ned to be extremely charitable. Other tools can interpret the type information m
ore aggressively and warn about violations of conventional (and sound) static ty
pe discipline. |
| 5844 } |
| 5845 |
| 5846 The name \DYNAMIC{} denotes a \cd{Type} object even though \DYNAMIC{} is not a c
lass. |
| 5847 |
| 5848 %\rationale { |
| 5849 %Type objects reify the runtime types of instances. No instance ever has type \D
YNAMIC{}. |
| 5850 %} |
| 5851 |
| 5852 \subsection{Type Void} |
| 5853 \label{typeVoid} |
| 5854 |
| 5855 The special type \VOID{} may only be used as the return type of a function: it i
s a compile-time error to use \VOID{} in any other context. |
| 5856 |
| 5857 \commentary{ |
| 5858 For example, as a type argument, or as the type of a variable or parameter |
| 5859 |
| 5860 Void is not an interface type. |
| 5861 |
| 5862 The only subtype relations that pertain to void are therefore: |
| 5863 \begin{itemize} |
| 5864 \item |
| 5865 $\VOID{} <: \VOID{}$ (by reflexivity) |
| 5866 \item |
| 5867 $\bot <: \VOID{}$ (as bottom is a subtype of all types). |
| 5868 \item |
| 5869 $\VOID{} <: \DYNAMIC{}$ (as \DYNAMIC{} is a supertype of all types) |
| 5870 \end{itemize} |
| 5871 |
| 5872 Hence, the static checker will issue warnings if one attempts to access a member
of the result of a void method invocation (even for members of \NULL{}, such as
\code{==}). Likewise, passing the result of a void method as a parameter or as
signing it to a variable will cause a warning unless the variable/formal paramet
er has type dynamic. |
| 5873 |
| 5874 On the other hand, it is possible to return the result of a void method from wit
hin a void method. One can also return \NULL{}; or a value of type \DYNAMIC{}. R
eturning any other result will cause a type warning. In checked mode, a dynamic
type error would arise if a non-null object was returned from a void method (sin
ce no object has runtime type \DYNAMIC{}). |
| 5875 } |
| 5876 |
| 5877 \commentary {The name \VOID{} does not denote a \cd{Type} object.} |
| 5878 |
| 5879 \rationale { |
| 5880 It is syntacticly illegal to use \VOID{} as an expression, and it would make no
sense to do so. |
| 5881 Type objects reify the runtime types of instances. No instance ever has type \VO
ID{}. |
| 5882 } |
| 5883 |
| 5884 |
| 5885 |
| 5886 \subsection{Parameterized Types} |
| 5887 \label{parameterizedTypes} |
| 5888 |
| 5889 A {\em parameterized type} is an invocation of a generic type declaration. |
| 5890 |
| 5891 Let $T$ be a parameterized type $G<S_1, \ldots, S_n>$. If $G$ is not a generic
type, the type arguments $S_i$, $1 \le i \le n$ are discarded. If $G$ has $m \n
e n$ type parameters, $T$ is treated as as a parameterized type with $m$ argumen
ts, all of which are \DYNAMIC{}. |
| 5892 |
| 5893 \commentary{In short, any arity mismatch results in all type arguments being dro
pped, and replaced with the correct number of type arguments, all set to \DYNAMI
C{}. Of course, a static warning will be issued. This behavior is not yet implem
ented. |
| 5894 } |
| 5895 |
| 5896 Otherwise, let |
| 5897 $T_i$ be the type parameters of $G$ and let $B_i$ be the bound of $T_i, i \in
1.. n$,. $T$ is {\em malbounded} iff either $S_i$ is malbounded or $S_i$ is not
a subtype of $[S_1, \ldots, S_n/T_1, \ldots, T_n]B_i, i \in 1.. n$. |
| 5898 |
| 5899 Note, that, in checked mode, it is a dynamic type error if a malbounded type is
used in a type test as specified in \ref{dynamicTypeSystem}. |
| 5900 |
| 5901 Any use of a malbounded type gives rise to a static warning. |
| 5902 |
| 5903 If $S$ is the static type of a member $m$ of $G$, then the static type of the me
mber $m$ of $G<A_1, \ldots, A_n>$ is $[A_1, \ldots, A_n/T_1, \ldots, T_n]S$
where $T_1, \ldots, T_n$ are the formal type parameters of $G$. Let $B_i$, be
the bounds of $T_i, 1 \le i \le n$. It is a static type warning if $A_i$ is not
a subtype of $[A_1, \ldots, A_n/T_1, \ldots, T_n]B_i, i \in 1..n$. It is a s
tatic type warning if $G$ is not a generic type with exactly $n$ type parameters
. |
| 5904 |
| 5905 |
| 5906 |
| 5907 |
| 5908 |
| 5909 \subsubsection{Actual Type of Declaration} |
| 5910 \label{actualTypeOfADeclaration} |
| 5911 |
| 5912 A type $T$ {\em depends on a type parameter} $U$ iff: |
| 5913 \begin{itemize} |
| 5914 \item $T$ is $U$. |
| 5915 \item $T$ is a parameterized type, and one of the type arguments of $T$ depends
on $U$. |
| 5916 \end{itemize} |
| 5917 |
| 5918 Let $T$ be the declared type of a declaration $d$, as it appears in the program
source. The {\em actual type} of $d$ is |
| 5919 |
| 5920 \begin{itemize} |
| 5921 \item $[A_1, \ldots, A_n/U_1, \ldots, U_n]T$ if $d$ depends on type parameters
$U_1, \ldots, U_n$, and $A_i$ is the value of $U_i, 1 \le i \le n$. |
| 5922 \item $T$ otherwise. |
| 5923 \end{itemize} |
| 5924 |
| 5925 \subsubsection{Least Upper Bounds} |
| 5926 \label{leastUpperBounds} |
| 5927 |
| 5928 Given two interfaces $I$ and $J$, let $S_I$ be the set of superinterfaces of $I$
, let $S_J$ be the set of superinterfaces of $J$ and let $S = (I \cup S_I) \ca
p (J \cup S_J)$. Furthermore, we define $S_n = \{T | T \in S \wedge depth(T) =
n\}$ for any finite $n$ %, and $k=max(depth(T_1), \ldots, depth(T_m)), T_i \in S
, i \in 1..m$, |
| 5929 where $depth(T)$ is the number of steps in the longest inheritance path from $T$
to \code{Object}. Let $q$ be the largest number such that $S_q$ has cardinality
one. The least upper bound of $I$ and $J$ is the sole element of $S_q$. |
| 5930 |
| 5931 % void, dynamic, type variables need to be figured into this. |
| 5932 |
| 5933 |
| 5934 |
| 5935 \section{Reference} |
| 5936 \label{reference} |
| 5937 |
| 5938 \subsection{Lexical Rules} |
| 5939 \label{lexicalRules} |
| 5940 |
| 5941 Dart source text is represented as a sequence of Unicode code points. This sequ
ence is first converted into a sequence of tokens according to the lexical rules
given in this specification. At any point in the tokenization process, the lon
gest possible token is recognized. |
| 5942 |
| 5943 \subsubsection{Reserved Words} |
| 5944 \label{reservedWords} |
| 5945 |
| 5946 A {\em reserved word} may not be used as an identifier; it is a compile-time err
or if a reserved word is used where an identifier is expected. |
| 5947 |
| 5948 \ASSERT{}, \BREAK{}, \CASE{}, \CATCH{}, \CLASS{}, \CONST{}, \CONTINUE{}, \DEFAUL
T{}, \DO{}, \ELSE{}, \ENUM{}, \EXTENDS{}, \FALSE{}, \FINAL{}, \FINALLY{}, \FOR{}
, \IF{}, \IN{}, \IS{}, \NEW{}, \NULL{}, \RETHROW, \RETURN{}, \SUPER{}, \SWITCH{}
, \THIS{}, \THROW{}, \TRUE{}, \TRY{}, \VAR{}, \VOID{}, \WHILE{}, \WITH{}. |
| 5949 |
| 5950 |
| 5951 |
| 5952 %\Q{Unicode characters.} |
| 5953 |
| 5954 \begin{grammar} |
| 5955 {\bf LETTER:}`a' {\escapegrammar ..} `z'; |
| 5956 `A' {\escapegrammar ..}`Z' |
| 5957 . |
| 5958 |
| 5959 {\bf DIGIT:} |
| 5960 `0' {\escapegrammar ..} `9' |
| 5961 . |
| 5962 |
| 5963 {\bf WHITESPACE:} |
| 5964 (`$\backslash$t' $|$ ` ' $|$ NEWLINE)+ |
| 5965 . |
| 5966 \end{grammar} |
| 5967 |
| 5968 \subsubsection{Comments} |
| 5969 \label{comments} |
| 5970 |
| 5971 {\em Comments} are sections of program text that are used for documentation. |
| 5972 |
| 5973 \begin{grammar}{\bf SINGLE\_LINE\_COMMENT:} |
| 5974 `//' \~{}(NEWLINE)* (NEWLINE)? |
| 5975 . |
| 5976 |
| 5977 {\bf MULTI\_LINE\_COMMENT:} |
| 5978 `/*' (MULTI\_LINE\_COMMENT $|$ \~{} `*/')* `*/' |
| 5979 . |
| 5980 \end{grammar} |
| 5981 |
| 5982 Dart supports both single-line and multi-line comments. A {\em single line comme
nt} begins with the token \code{//}. Everything between \code{//} and the end of
line must be ignored by the Dart compiler unless the comment is a documentation
comment. . |
| 5983 |
| 5984 A {\em multi-line comment} begins with the token \code{/*} and ends with the tok
en \code{*/}. Everything between \code{/}* and \code{*}/ must be ignored by the
Dart compiler unless the comment is a documentation comment. Comments may nest.
|
| 5985 |
| 5986 {\em Documentation comments} are comments that begin with the tokens \code{///}
or \code{/**}. Documentation comments are intended to be processed by a tool t
hat produces human readable documentation. |
| 5987 |
| 5988 The scope of a documentation comment always excludes the imported namespace of
the enclosing library. Only names declared in the enclosing library are consider
ed in scope within a documentation comment. |
| 5989 |
| 5990 The scope of a documentation comment immediately preceding the declaration of a
class $C$ is the instance scope of $C$, excluding any names introduced via the i
mport namespace of the enclosing library. |
| 5991 |
| 5992 The scope of a documentation comment immediately preceding the declaration of a
function $f$ is the scope in force at the very beginning of the body of $f$,
excluding any names introduced via the import namespace of the enclosing library
. |
| 5993 |
| 5994 |
| 5995 |
| 5996 |
| 5997 |
| 5998 %\subsection{Grammar} |
| 5999 \subsection{Operator Precedence} |
| 6000 \label{operatorPrecedence} |
| 6001 |
| 6002 Operator precedence is given implicitly by the grammar. |
| 6003 |
| 6004 \commentary{The following non-normative table may be helpful |
| 6005 \newline |
| 6006 |
| 6007 \begin{tabular}{| r | r | r | r |} |
| 6008 \hline |
| 6009 Description & Operator & Associativity & Precedence \\ |
| 6010 \hline |
| 6011 Unary postfix & ., ?id, e++, e--, e1[e2], e1() , () & None & 15 \\ |
| 6012 \hline |
| 6013 Unary prefix & -e, !e, \~{}e, ++e, --e & None & 14\\ |
| 6014 \hline |
| 6015 Multiplicative & *, /, \~/, \% & Left & 13\\ |
| 6016 \hline |
| 6017 Additive & +, - & Left & 12\\ |
| 6018 \hline |
| 6019 Shift & $<<$, $>>$& Left & 11\\ |
| 6020 \hline |
| 6021 Bitwise AND & \& & Left & 10\\ |
| 6022 \hline |
| 6023 Bitwise XOR & \^{} & Left & 9\\ |
| 6024 \hline |
| 6025 Bitwise Or & $|$ & Left & 8\\ |
| 6026 \hline |
| 6027 Relational & $<$, $>$, $<=$, $>=$, \AS{}, \IS{}, \IS{}! & None & 7\\ |
| 6028 \hline |
| 6029 Equality & ==, != & None & 6\\ |
| 6030 \hline |
| 6031 Logical AND & \&\& & Left & 5\\ |
| 6032 \hline |
| 6033 Logical Or & $||$ & Left & 4\\ |
| 6034 \hline |
| 6035 Conditional & e1? e2: e3 & None & 3\\ |
| 6036 \hline |
| 6037 Cascade & .. & Left & 2\\ |
| 6038 \hline |
| 6039 Assignment & =, *=, /=, +=, -= ,\&=, \^{}= etc. & Right & 1\\ |
| 6040 \hline |
| 6041 \end{tabular} |
| 6042 } |
| 6043 %\subsection{Glossary} |
| 6044 |
| 6045 %\bibliographystyle{alpha} |
| 6046 %\bibliography{/users/gilad/research/bibs/master} |
| 6047 \section*{Appendix: Naming Conventions} |
| 6048 |
| 6049 \commentary{ |
| 6050 The following naming conventions are customary in Dart programs. |
| 6051 \begin{itemize} |
| 6052 \item The names of compile time constant variables never use lower case letters.
If they consist of multiple words, those words are separated by underscores. Ex
amples: PI, I\_AM\_A\_CONSTANT. |
| 6053 \item The names of functions (including getters, setters, methods and local or l
ibrary functions) and non-constant variables begin with a lowercase letter. If t
he name consists of multiple words, each word (except the first) begins with an
uppercase letter. No other uppercase letters are used. Examples: camlCase, dar
t4TheWorld |
| 6054 \item The names of types (including classes and type aliases) begin with an uppe
r case letter. If the name consists of multiple words, each word begins with
an uppercase letter. No other uppercase letters are used. Examples: CamlCase, D
art4TheWorld. |
| 6055 \item The names of type variables are short (preferably single letter). Examples
: T, S, K, V , E. |
| 6056 \item The names of libraries or library prefixes never use upper case letters. I
f they consist of multiple words, those words are separated by underscores. Exam
ple: my\_favorite\_library. |
| 6057 \end{itemize} |
| 6058 } |
| 6059 |
| 6060 |
| 6061 \end{document} |
OLD | NEW |