diff --git a/specification/dartLangSpec.tex b/specification/dartLangSpec.tex index ec0eab9c68..2e037491ed 100644 --- a/specification/dartLangSpec.tex +++ b/specification/dartLangSpec.tex @@ -37,20 +37,20 @@ % behavior of tools. % - Eliminate error for library name conflicts in imports and exports. % - Clarify the specification of initializing formals. Fix error: Add -% missing `?' at the end for function typed initializing formal. +% missing `?` at the end for function typed initializing formal. % - Adjust specification of JS number semantics. % - Revise and clarify the sections Imports and Exports. % - Bug fix: Change to omit the single identifier, then add it % back when is used, as resp. . % - Clarify that a function-type bounded receiver has a `.call` method. -% - Merge the 'static' and 'instance' scope of a class, yielding a single -% 'class' scope. +% - Merge the `static' and `instance' scope of a class, yielding a single +% `class' scope. % - Add specification of `>>` in JavaScript compiled code, in appendix. % - Integrate the specification of extension methods into this document. % - Specify identifier references denoting extension members. % - Remove a few null safety features, to enable publishing a stable % version of the specification which is purely about Dart 2.10. -% - Reorganize specification of type aliases to be in section 'Type Aliases' +% - Reorganize specification of type aliases to be in section `Type Aliases' % (this used to be both there, and in 'Generics'). % - Clarify the cyclicity error for type aliases ("F is not allowed to depend % on itself). @@ -64,7 +64,7 @@ % 'class declaration' everywhere, so `` is inconsistent). % - Clarify that and are the % start symbols of the grammar. -% - Clarify the notion of being 'noSuchMethod forwarded': `m` is indeed +% - Clarify the notion of being `noSuchMethod forwarded': `m` is indeed % noSuchMethod forwarded if an implementation of `m` is inherited, but % it does not have the required signature. % - Clarify static checks on `yield` and `yield*` to explicitly ensure that @@ -93,7 +93,7 @@ % invocation. % % 2.4 -% - Clarify the section 'Exports'. +% - Clarify the section `Exports'. % - Update grammar rules for , to support `static late final` % variables with no initializer; for several top-level declarations, % to correct the existence and placement of ; for @@ -111,7 +111,7 @@ % - Correct several grammar rules, including: added (to % avoid semicolon in ), adjusted . % - Revise section on cascades. Now uses compositional grammar, and -% specifies static type, compile-time errors, and includes `?..'. +% specifies static type, compile-time errors, and includes `?..`. % - Correct the grammar and lexical rules for string literals. % - Change specification of `await` to be type-safe, avoiding cases like: % FutureOr> ffs = Future.value(s); @@ -238,8 +238,8 @@ % and that the `int` class is intended as signed 64-bit integer, but % that platforms may differ. % - Specify variance and super-bounded types. -% - Introduce `subterm` and `immediate subterm`. -% - Introduce `top type`. +% - Introduce `subterm' and `immediate subterm'. +% - Introduce `top type'. % - Specify configurable imports. % - Specify the dynamic type of the Iterable/Future/Stream returned from % invocations of functions marked sync*/async/async*. @@ -298,7 +298,7 @@ % In many cases, the rewrite wasn't safe for asynchronous code. % - Removed generalized tear-offs. % - Allow "rethrow" to also end a switch case. Allow braces around switch cases. -% - Allow using '=' as default-value separator for named parameters. +% - Allow using `=` as default-value separator for named parameters. % - Make it a compile-time error if a library includes the same part twice. % - Now more specific about the return types of sync*/async/async* functions % in relation to return statements. @@ -341,15 +341,24 @@ \section{Scope} \LMLabel{ecmaScope} \LMHash{}% -This Ecma standard specifies the syntax and semantics of the Dart programming language. -It does not specify the APIs of the Dart libraries except where those library elements are essential to the correct functioning of the language itself (e.g., the existence of class \code{Object} with methods such as \code{noSuchMethod}, \code{runtimeType}). +This Ecma standard specifies the syntax and semantics of +the Dart programming language. +It does not specify the APIs of the Dart libraries +except where those library elements are essential to +the correct functioning of the language itself +(e.g., the existence of class \code{Object} with methods +such as \code{noSuchMethod}, \code{runtimeType}). \section{Conformance} \LMLabel{ecmaConformance} \LMHash{}% -A conforming implementation of the Dart programming language must provide and support all the APIs (libraries, types, functions, getters, setters, whether top-level, static, instance or local) mandated in this specification. +A conforming implementation of the Dart programming language +must provide and support all the APIs +(libraries, types, functions, getters, setters, +whether top-level, static, instance or local) +mandated in this specification. \LMHash{}% A conforming implementation is permitted to provide additional APIs, @@ -361,9 +370,11 @@ \section{Normative References} \LMLabel{ecmaNormativeReferences} \LMHash{}% -The following referenced documents are indispensable for the application of this document. +The following referenced documents are indispensable for +the application of this document. For dated references, only the edition cited applies. -For undated references, the latest edition of the referenced document (including any amendments) applies. +For undated references, the latest edition of the referenced document +(including any amendments) applies. \begin{enumerate} \item @@ -377,7 +388,8 @@ \section{Terms and Definitions} \LMLabel{ecmaTermsAndDefinitions} \LMHash{}% -Terms and definitions used in this specification are given in the body of the specification proper. +Terms and definitions used in this specification are given in +the body of the specification proper. % End Ecma Boilerplate @@ -397,7 +409,13 @@ \section{Notation} what part of the text is binding and what part is merely expository.% } \item[Commentary] - Comments such as ``\commentary{The careful reader will have noticed that the name Dart has four characters}'' serve to illustrate or clarify the specification, but are redundant with the normative text. + Comments such as + ``\commentary{% + The careful reader will have noticed + that the name Dart has four characters% + }'' + serve to illustrate or clarify the specification, + but are redundant with the normative text. \commentary{% The difference between commentary and rationale can be subtle.% } @@ -413,7 +431,7 @@ \section{Notation} appear in {\bf bold}. \commentary{% -Examples would be \SWITCH{} or \CLASS{}.% +Examples would be \SWITCH{} or \CLASS.% } \LMHash{}% @@ -455,12 +473,16 @@ \section{Notation} \LMHash{}% Both syntactic and lexical productions are represented this way. Lexical productions are distinguished by their names. -The names of lexical productions consist exclusively of upper case characters and underscores. -As always, within grammatical productions, whitespace and comments between elements of the production are implicitly ignored unless stated otherwise. +The names of lexical productions consist exclusively of +upper case characters and underscores. +As always, within grammatical productions, +whitespace and comments between elements of the production +are implicitly ignored unless stated otherwise. Punctuation tokens appear in quotes. \LMHash{}% -Productions are embedded, as much as possible, in the discussion of the constructs they represent. +Productions are embedded, as much as possible, +in the discussion of the constructs they represent. \LMHash{}% A \Index{term} is a syntactic construct. @@ -493,9 +515,11 @@ \section{Notation} \LMHash{}% This operation is also known as \Index{substitution}, and it is the variant that avoids capture. -That is, when $E$ contains a construct that introduces $y_i$ into a nested scope for some $i \in 1 .. n$, +That is, when $E$ contains a construct that introduces $y_i$ into +a nested scope for some $i \in 1 .. n$, the substitution will not replace $y_i$ in that scope. -Conversely, if such a replacement would put an identifier \id{} (a subterm of $x_i$) into a scope where \id{} is declared, +Conversely, if such a replacement would put an identifier \id{} +(a subterm of $x_i$) into a scope where \id{} is declared, the relevant declarations in $E$ are systematically renamed to fresh names. \commentary{% @@ -515,7 +539,8 @@ \section{Notation} \BlindDefineSymbol{x, op, y}% The specifications of operators often involve statements such as \code{$x$ \metavar{op} $y$} is equivalent to the method invocation -\IndexCustom{\rm\code{$x$.\metavar{op}($y$)}}{x.op(y)@\code{$x$.\metavar{op}($y$)}}. +\IndexCustom{\rm\code{$x$.\metavar{op}($y$)}}{% + x.op(y)@\code{$x$.\metavar{op}($y$)}}. Such specifications should be understood as a shorthand for: \begin{itemize} \item @@ -718,9 +743,13 @@ \section{Overview} \LMLabel{overview} \LMHash{}% -Dart is a class-based, single-inheritance, pure object-oriented programming language. +Dart is a class-based, single-inheritance, pure +object-oriented programming language. 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 class \code{Object}, the root of the Dart class hierarchy. +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 class \code{Object}, +the root of the Dart class hierarchy. \LMHash{}% Dart programs may be statically checked. @@ -843,7 +872,7 @@ \subsection{Scoping} \LMHash{}% Let \NamespaceName{} be a namespace. We say that a name $n$ \Index{is in} \NamespaceName{} -if $n$ is a key of \NamespaceName{}. +if $n$ is a key of \NamespaceName. We say a declaration $d$ \NoIndex{is in} \NamespaceName{} if a key of \NamespaceName{} is mapped to $d$. @@ -1181,7 +1210,8 @@ \section{Variables} ::= (`=' )? - ::= (`,' )* + ::= + (`,' )* \end{grammar} \LMHash{}% @@ -1203,12 +1233,12 @@ \section{Variables} } \LMHash{}% -It is possible for a variable declaration to include the modifier \COVARIANT{}. +It is possible for a variable declaration to include the modifier \COVARIANT. The effect of doing this with an instance variable is described elsewhere (\ref{instanceVariables}). It is a compile-time error for the declaration of a variable which is not an instance variable -to include the modifier \COVARIANT{}. +to include the modifier \COVARIANT. \LMHash{}% In a variable declaration of one of the forms @@ -1244,14 +1274,19 @@ \section{Variables} is a variable that is not associated with a particular instance, but rather with an entire library or class. Static variables include library variables and class variables. -Class variables are variables whose declaration is immediately nested inside a class declaration and includes the modifier \STATIC{}. +Class variables are variables whose declaration 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{}. +It is a compile-time error to preface a top-level variable declaration +with the built-in identifier (\ref{identifierReference}) \STATIC. \LMHash{}% A \IndexCustom{constant variable}{variable!constant} -is a variable whose declaration includes the modifier \CONST{}. -A constant variable must be initialized to a constant expression (\ref{constants}) or a compile-time error occurs. +is a variable whose declaration includes the modifier \CONST. +A constant variable must be initialized to a constant expression +(\ref{constants}) +or a compile-time error occurs. \commentary{% An initializing expression of a constant variable occurs in a constant context @@ -1265,7 +1300,7 @@ \section{Variables} a final variable $v$ will always refer to the same object after $v$ has been initialized. A variable is final if{}f its declaration includes -the modifier \FINAL{} or the modifier \CONST{}. +the modifier \FINAL{} or the modifier \CONST. \LMHash{}% A \IndexCustom{mutable variable}{variable!mutable} @@ -1372,7 +1407,7 @@ \section{Variables} Similarly, assignment to a final instance variable $v$ is a compile-time error, unless a setter named \code{$v$=} is in scope, -or the receiver has type \DYNAMIC{}. +or the receiver has type \DYNAMIC. $v$ can be initialized in its declaration or in initializer lists, but initialization and assignment is not the same thing. When the receiver has type \DYNAMIC{} @@ -1451,42 +1486,42 @@ \subsection{Evaluation of Implicit Variable Getters} then the implicit getter method of $v$ executes as follows: \begin{itemize} \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 object has yet been stored into $v$ -then the initializing expression $e$ is evaluated. -If, during the evaluation of $e$, the getter for $v$ is invoked, -a \code{CyclicInitializationError} is thrown. -If the evaluation of $e$ throws an exception $e$ and stack trace $s$, -the null object (\ref{null}) is stored into $v$; -the execution of the getter then throws $e$ and stack trace $s$. -Otherwise, the evaluation of $e$ succeeded yielding an object $o$; -then $o$ is stored into $v$ and -the execution of the getter completes by returning $o$. -Otherwise, -(\commentary{when an object $o$ has been stored in $v$}) -execution of the getter completes by returning $o$. + 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 object has yet been stored into $v$ + then the initializing expression $e$ is evaluated. + If, during the evaluation of $e$, the getter for $v$ is invoked, + a \code{CyclicInitializationError} is thrown. + If the evaluation of $e$ throws an exception $e$ and stack trace $s$, + the null object (\ref{null}) is stored into $v$; + the execution of the getter then throws $e$ and stack trace $s$. + Otherwise, the evaluation of $e$ succeeded yielding an object $o$; + then $o$ is stored into $v$ and + the execution of the getter completes by returning $o$. + Otherwise, + (\commentary{when an object $o$ has been stored in $v$}) + execution of the getter completes by returning $o$. \item {\bf Constant variable declaration}. -If $d$ is of one of the forms -\code{\CONST{} $v$ = $e$;}, -\code{\CONST{} $T$ $v$ = $e$;}, -\code{\STATIC{} \CONST{} $v$ = $e$;} or -\code{\STATIC{} \CONST{} $T$ $v$ = $e$;} -the result of the getter is the value of the constant expression $e$. -\commentary{% -Note that a constant expression cannot depend on itself, -so no cyclic references can occur.% -} + If $d$ is of one of the forms + \code{\CONST{} $v$ = $e$;}, + \code{\CONST{} $T$ $v$ = $e$;}, + \code{\STATIC{} \CONST{} $v$ = $e$;} or + \code{\STATIC{} \CONST{} $T$ $v$ = $e$;} + the result of the getter is the value of the constant expression $e$. + \commentary{% + Note that a constant expression cannot depend on itself, + so no cyclic references can occur.% + } \item {\bf Variable declaration without initializer}. -The result of executing the getter method is the object stored in $v$. -\commentary{This may be the initial value, that is, the null object.} + The result of executing the getter method is the object stored in $v$. + \commentary{This may be the initial value, that is, the null object.} \end{itemize} @@ -1509,7 +1544,8 @@ \section{Functions} \end{grammar} \LMHash{}% -Functions can be introduced by function declarations (\ref{functionDeclarations}), +Functions can be introduced by function declarations +(\ref{functionDeclarations}), method declarations (\ref{instanceMethods}, \ref{staticMethods}), getter declarations (\ref{getters}), setter declarations (\ref{setters}), @@ -1596,8 +1632,9 @@ \section{Functions} Let $T$ be the declared return type of the function that has this body. It is a compile-time error if one of the following conditions hold: \begin{itemize} - \item The function is synchronous, $T$ is not \VOID{}, - and it would have been a compile-time error to declare the function with the body + \item The function is synchronous, $T$ is not \VOID, + and it would have been a compile-time error + to declare the function with the body \code{\{ \RETURN{} $e$; \}} rather than \code{=> $e$}. \commentary{% @@ -1613,7 +1650,7 @@ \section{Functions} that the returned object will not be used (\ref{return}).% } - \item The function is asynchronous, \flatten{T} is not \VOID{}, + \item The function is asynchronous, \flatten{T} is not \VOID, and it would have been a compile-time error to declare the function with the body \code{\ASYNC{} \{ \RETURN{} $e$; \}} @@ -1650,7 +1687,7 @@ \section{Functions} If you need to produce an object asynchronously, use a method. One could allow modifiers for factories. -A factory for \code{Future} could be modified by \ASYNC{}, +A factory for \code{Future} could be modified by \ASYNC, a factory for \code{Stream} could be modified by \code{\ASYNC*}, and a factory for \code{Iterable} could be modified by \code{\SYNC*}. No other scenario makes sense because @@ -1691,7 +1728,7 @@ \section{Functions} then the element type of $f$ is \DYNAMIC. \commentary{% -%% TODO(eernst): Come nnbd, change 'a top type' to \DYNAMIC. +%% TODO(eernst): Come nnbd, change `a top type' to \DYNAMIC. In the latter case the return type is a top type, because the declaration of $f$ would otherwise be a compile-time error. This implies that there is no information about @@ -1731,10 +1768,10 @@ \subsection{Function Declarations} \LMHash{}% It is a compile-time error to preface a function declaration -with the built-in identifier \STATIC{}. +with the built-in identifier \STATIC. \LMHash{}% -When we say that a function $f_1$ \Index{forwards} to another function $f_2$, +When we say that a function $f_1$ \Index{forwards} to another function $f_2$, we mean that invoking $f_1$ causes $f_2$ to be executed with the same arguments and/or receiver as $f_1$, and returns the result of executing $f_2$ to the caller of $f_1$, @@ -1794,12 +1831,13 @@ \subsection{Formal Parameters} in the bounds of parameter declarations, allowing for so-called F-bounded type parameters like -\code{class C{}> \{ \ldots{} \}}, +\noindent +\code{class C{}> \{ \ldots\ \}}, \noindent and the formal type parameters are in scope for each other, allowing dependencies like -\code{class D \{ \ldots{} \}}.% +\code{class D \{ \ldots\ \}}.% } \LMHash{}% @@ -1952,14 +1990,18 @@ \subsubsection{Optional Formals} is equivalent to the form \syntax{ `=' }. The colon-syntax is included only for backwards compatibility. -It is deprecated and will be removed in a later version of the language specification. +It is deprecated and will be removed in +a later version of the language specification. \LMHash{}% -It is a compile-time error if the default value of an optional parameter is not a constant expression (\ref{constants}). -If no default is explicitly specified for an optional parameter an implicit default of \NULL{} is provided. +It is a compile-time error if the default value of an optional parameter is +not a constant expression (\ref{constants}). +If no default is explicitly specified for an optional parameter +an implicit default of \NULL{} is provided. \LMHash{}% -It is a compile-time error if the name of a named optional parameter begins with an `_' character. +It is a compile-time error if the name of a named optional parameter +begins with an `_' character. \rationale{% The need for this restriction is a direct consequence of @@ -1969,7 +2011,7 @@ \subsubsection{Optional Formals} callers from outside the library where it was defined. If a method outside the library overrode a method with a private optional name, it would not be a subtype of the original method. -The static checker would of course flag such situations, +The static checker would of course flag such situations, but the consequence would be that adding a private named formal would break clients outside the library in a way they could not easily correct.% } @@ -1981,7 +2023,7 @@ \subsubsection{Covariant Parameters} \LMHash{}% Dart allows formal parameters of instance methods, including setters and operators, -to be declared \COVARIANT{}. +to be declared \COVARIANT. \commentary{% The syntax for doing this is specified in an earlier section @@ -2065,7 +2107,7 @@ \subsubsection{Covariant Parameters} \BlindDefineSymbol{C, m, p}% Let $C$ be a class that declares a method $m$ which has -a parameter $p$ whose declaration has the modifier \COVARIANT{}; +a parameter $p$ whose declaration has the modifier \COVARIANT; in this case we say that the parameter $p$ is \IndexCustom{covariant-by-declaration}{parameter!covariant-by-declaration}. % @@ -2174,7 +2216,7 @@ \subsection{Type of a Function} unless it is a constructor, in which case it is not considered to have a return type, or it is a setter or operator \code{[]=}, -in which case its return type is \VOID{}. +in which case its return type is \VOID. \LMHash{}% A function declaration may declare formal type parameters. @@ -2243,7 +2285,7 @@ \subsection{Type of a Function} $T$ may contain free type variables, but $t$ contains their actual values.% } The following must then hold: -$u$ is a class that implements the built-in class \FUNCTION{}; +$u$ is a class that implements the built-in class \FUNCTION; $u$ is a subtype of $t$; and $u$ is not a subtype of any function type which is a proper subtype of $t$. \commentary{% @@ -2330,7 +2372,8 @@ \section{Classes} \LMHash{}% A \Index{class} defines the form and behavior of a set of objects which are its \IndexCustom{instances}{instance}. -Classes may be defined by class declarations as described below, or via mixin applications (\ref{mixinApplication}). +Classes may be defined by class declarations as described below, +or via mixin applications (\ref{mixinApplication}). \begin{grammar} ::= @@ -2376,7 +2419,8 @@ \section{Classes} \end{grammar} \LMHash{}% -It is possible to include the modifier \COVARIANT{} in some forms of declarations. +It is possible to include the modifier \COVARIANT{} +in some forms of declarations. The effect of doing this is described elsewhere (\ref{covariantParameters}). @@ -2414,7 +2458,7 @@ \section{Classes} (\commentary{and hence its members}) can only be accessed at specific locations in a class: We say that a location $\ell$ -\IndexCustom{has access to \THIS{}}{has access to this@has access to \THIS{}} +\IndexCustom{has access to \THIS}{has access to this@has access to \THIS} if{}f $\ell$ is inside the body of a declaration of an instance member or a generative constructor, or in the initializing expression of a \LATE{} instance variable declaration. @@ -2466,7 +2510,7 @@ \section{Classes} that name denotes the interface of the class. \LMHash{}% -% The use of 'concrete member' below may seem redundant, because a class +% The use of `concrete member' below may seem redundant, because a class % does not inherit abstract members from its superclass, but this % underscores the fact that even when an abstract declaration of $m$ is % declared in $C$, $C$ does not "have" $m$. @@ -2524,8 +2568,8 @@ \section{Classes} \\ \CLASS{} B \EXTENDS{} A \{ int i = 1; // \comment{getter i and setter i= override versions from A} - \STATIC{} j; // \comment{compile-time error: static getter \& setter conflict with} - // \comment{instance getter \& setter} + \STATIC{} j; // \comment{compile-time error: static getter \& setter conflict} + // \comment{with instance getter \& setter} \\ // \comment{compile-time error: static method conflicts with instance method} \STATIC{} f(x) => 3; @@ -2549,7 +2593,7 @@ \subsection{Instance Methods} \IndexCustom{Instance methods}{method!instance} are functions (\ref{functions}) whose declarations are immediately contained within a class declaration -and that are not declared \STATIC{}. +and that are not declared \STATIC. The \Index{instance methods of a class} $C$ are the instance methods declared by $C$ and the instance methods inherited by $C$ from its superclass @@ -2561,7 +2605,7 @@ \subsection{Instance Methods} and an instance member declaration $D$ in $C$, with member signature $m$ (\ref{interfaces}). It is a compile-time error if $D$ overrides a declaration -% Note that $m'$ is accessible, due to the definition of 'overrides'. +% Note that $m'$ is accessible, due to the definition of `overrides'. with member signature $m'$ from a direct superinterface of $C$ (\ref{interfaceInheritanceAndOverriding}), @@ -2642,7 +2686,9 @@ \subsubsection{Operators} \end{grammar} \LMHash{}% -An operator declaration is identified using the built-in identifier (\ref{identifierReference}) \OPERATOR{}. +An operator declaration is identified using the built-in identifier +(\ref{identifierReference}) +\OPERATOR. \LMHash{}% The following names are allowed for user-defined operators: @@ -2670,7 +2716,8 @@ \subsubsection{Operators} \LMHash{}% It is a compile-time error if the arity of the user-declared operator \lit{[]=} is not 2. -It is a compile-time error if the arity of a user-declared operator with one of the names: +It is a compile-time error if the arity of a user-declared operator +with one of the names: \lit{<}, \lit{>}, \lit{<=}, @@ -2719,7 +2766,7 @@ \subsubsection{Operators} \LMHash{}% It is a compile-time error if a user-declared operator \lit{[]=} -declares a return type other than \VOID{}. +declares a return type other than \VOID. \commentary{% If no return type is specified for a user-declared operator @@ -2863,8 +2910,8 @@ \subsubsection{The Method \code{noSuchMethod}} which is not a noSuchMethod forwarder. \LMHash{}% -%% TODO(eernst): We used to say 'the interface of $C$ or $D$'; but we -%% need to change 'accessible' to a scheme similar to name-merging everywhere +%% TODO(eernst): We used to say `the interface of $C$ or $D$'; but we +%% need to change `accessible' to a scheme similar to name-merging everywhere %% in order to be able to say this precisely. A noSuchMethod forwarder is a concrete member of $C$ with the signature taken from the interface of $C$, @@ -2938,10 +2985,10 @@ \subsubsection{The Method \code{noSuchMethod}} At the beginning of this section we mentioned that implicit invocations of \code{noSuchMethod} can only occur with a receiver of static type \DYNAMIC{} -or a function of static type \DYNAMIC{} or \FUNCTION{}. +or a function of static type \DYNAMIC{} or \FUNCTION. With a \code{noSuchMethod} forwarder, \code{noSuchMethod} can also be invoked -on a receiver whose static type is not \DYNAMIC{}. +on a receiver whose static type is not \DYNAMIC. No similar situation exists for functions, because it is impossible to induce a \code{noSuchMethod} forwarder into the class of a function object.% @@ -3116,17 +3163,19 @@ \subsection{Getters} \LMLabel{getters} \LMHash{}% -Getters are functions (\ref{functions}) that are used to retrieve the values of object properties. +Getters are functions (\ref{functions}) that are used +to retrieve the values of object properties. \begin{grammar} ::= ? \GET{} \end{grammar} \LMHash{}% -If no return type is specified, the return type of the getter is \DYNAMIC{}. +If no return type is specified, the return type of the getter is \DYNAMIC. \LMHash{}% -A getter definition that is prefixed with the \STATIC{} modifier defines a static getter. +A getter definition that is prefixed with the \STATIC{} modifier defines +a static getter. Otherwise, it defines an instance getter. The name of the getter is given by the identifier in the definition. @@ -3153,7 +3202,8 @@ \subsection{Setters} \LMLabel{setters} \LMHash{}% -Setters are functions (\ref{functions}) that are used to set the values of object properties. +Setters are functions (\ref{functions}) that are used to set +the values of object properties. \begin{grammar} ::= ? \SET{} @@ -3165,9 +3215,11 @@ \subsection{Setters} } \LMHash{}% -A setter definition that is prefixed with the \STATIC{} modifier defines a static setter. +A setter definition that is prefixed with the \STATIC{} modifier defines +a static setter. Otherwise, it defines an instance setter. -The name of a setter is obtained by appending the string `=' to the identifier given in its signature. +The name of a setter is obtained by appending the string `=' to +the identifier given in its signature. \commentary{% Hence, a setter name can never conflict with, override or be overridden by @@ -3215,7 +3267,8 @@ \subsection{Abstract Instance Members} (respectively, \IndexCustom{abstract getter}{getter!abstract} or \IndexCustom{abstract setter}{setter!abstract}) -is an instance method, getter or setter that is not declared \EXTERNAL{} and does not provide an implementation. +is an instance method, getter or setter that is not declared \EXTERNAL{} +and does not provide an implementation. A \IndexCustom{concrete method}{method!concrete} (respectively, \IndexCustom{concrete getter}{getter!concrete} or @@ -3288,7 +3341,7 @@ \subsection{Instance Variables} \IndexCustom{Instance variables}{variables!instance} are variables whose declarations are immediately contained within a class declaration -and that are not declared \STATIC{}. +and that are not declared \STATIC. The \Index{instance variables of a class} $C$ are the instance variables declared by $C$ and the instance variables inherited by $C$ from its superclass. @@ -3326,7 +3379,7 @@ \subsection{Instance Variables} \commentary{% The modifier \COVARIANT{} on an instance variable has no other effects. In particular, the return type of the implicitly induced getter -can already be overridden covariantly without \COVARIANT{}, +can already be overridden covariantly without \COVARIANT, and it can never be overridden to a supertype or an unrelated type, regardless of whether the modifier \COVARIANT{} is present.% } @@ -3336,12 +3389,18 @@ \subsection{Constructors} \LMLabel{constructors} \LMHash{}% -A \Index{constructor} is a special function that is used in instance creation expressions (\ref{instanceCreation}) to obtain objects, typically by creating or initializing them. -Constructors may be generative (\ref{generativeConstructors}) or they may be factories (\ref{factories}). +A \Index{constructor} is a special function that is used +in instance creation expressions (\ref{instanceCreation}) to obtain objects, +typically by creating or initializing them. +Constructors may be generative (\ref{generativeConstructors}) +or they may be factories (\ref{factories}). \LMHash{}% -A \Index{constructor name} always begins with the name of its immediately enclosing class, and may optionally be followed by a dot and an identifier \id. -It is a compile-time error if the name of a constructor is not a constructor name. +A \Index{constructor name} always begins with +the name of its immediately enclosing class, +and may optionally be followed by a dot and an identifier \id. +It is a compile-time error if the name of a constructor +is not a constructor name. \LMHash{}% The @@ -3441,15 +3500,20 @@ \subsubsection{Generative Constructors} the formal parameter scope (\ref{formalParameters}). When the formal parameter list of a non-redirecting generative constructor contains any initializing formals, a new scope is introduced, the -\IndexCustom{formal parameter initializer scope}{scope!formal parameter initializer}, +\IndexCustom{formal parameter initializer scope}{% + scope!formal parameter initializer}, which is the current scope of the initializer list of the constructor, and which is enclosed in the scope where the constructor is declared. -Each initializing formal in the formal parameter list introduces a final local variable into the formal parameter initializer scope, but not into the formal parameter scope; every other formal parameter introduces a local variable into both the formal parameter scope and the formal parameter initializer scope. +Each initializing formal in the formal parameter list +introduces a final local variable into the formal parameter initializer scope, +but not into the formal parameter scope; +every other formal parameter introduces a local variable into +both the formal parameter scope and the formal parameter initializer scope. \commentary{% This means that formal parameters, including initializing formals, must have distinct names, and that initializing formals -are in scope for the initializer list, +are in scope for the initializer list, but they are not in scope for the body of the constructor. When a formal parameter introduces a local variable into two scopes, it is still one variable and hence one storage location. @@ -3460,12 +3524,12 @@ \subsubsection{Generative Constructors} \LMHash{}% Initializing formals are executed during the execution of generative constructors detailed below. -Executing an initializing formal \code{\THIS{}.\id} +Executing an initializing formal \code{\THIS.\id} causes the instance variable \id{} of the immediately surrounding class to be assigned the value of the corresponding actual parameter, % This can occur due to a failing implicit cast. unless the assigned object has a dynamic type -which is not a subtype of the declared type of the instance variable \id{}, +which is not a subtype of the declared type of the instance variable \id, in which case a dynamic error occurs. \commentary{% @@ -3491,12 +3555,14 @@ \subsubsection{Generative Constructors} \end{dartCode} \LMHash{}% -A \Index{fresh instance} is an instance whose identity is distinct from any previously allocated instance of its class. -A generative constructor always operates on a fresh instance of its immediately enclosing class. +A \Index{fresh instance} is an instance whose identity is distinct from +any previously allocated instance of its class. +A generative constructor always operates on a fresh instance of +its immediately enclosing class. \commentary{% -The above holds if the constructor is actually run, as it is by \NEW{}. -If a constructor $c$ is referenced by \CONST{}, $c$ may not be run; +The above holds if the constructor is actually run, as it is by \NEW. +If a constructor $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{instanceCreation}).% } @@ -3550,7 +3616,7 @@ \subsubsection{Generative Constructors} \code{$\THIS{}$($e_1 \ldots,\ e_p,\ x_1$:\ $e_{p+1}, \ldots,\ x_q$:\ $e_{p+q}$)} \noindent -\code{$\THIS{}.\id$($e_1 \ldots,\ e_p,\ x_1$:\ $e_{p+1}, \ldots,\ x_q$:\ $e_{p+q}$)}. +\code{$\THIS.\id$($e_1 \ldots,\ e_p,\ x_1$:\ $e_{p+1}, \ldots,\ x_q$:\ $e_{p+q}$)}. \LMHash{}% The @@ -3584,9 +3650,9 @@ \subsubsection{Generative Constructors} } \LMHash{}% -When $\ConstMetavar$ is \CONST{}, +When $\ConstMetavar$ is \CONST, it is a compile-time error if the redirectee is not a constant constructor. -Moreover, when $\ConstMetavar$ is \CONST{}, each +Moreover, when $\ConstMetavar$ is \CONST, each $e_i,\ i \in 1 .. p+q$, must be a potentially constant expression (\ref{constantConstructors}). @@ -3641,7 +3707,7 @@ \subsubsection{Generative Constructors} \LMHash{}% An initializer of the form \code{$v$ = $e$} is equivalent to -an initializer of the form \code{\THIS{}.$v$ = $e$}, +an initializer of the form \code{\THIS.$v$ = $e$}, both forms are called \Index{instance variable initializers}. It is a compile-time error if the enclosing class does not declare an instance variable named $v$. @@ -3652,11 +3718,11 @@ \subsubsection{Generative Constructors} Consider a \Index{superinitializer} $s$ of the form \noindent -\code{\SUPER{}($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)} +\code{\SUPER($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)} respectively \noindent -\code{\SUPER{}.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}. +\code{\SUPER.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}. \noindent{}% Let $S$ be the superclass of the enclosing class of $s$. @@ -3664,7 +3730,7 @@ \subsubsection{Generative Constructors} a generative constructor named $S$ (respectively \code{$S$.\id}). Otherwise, the static analysis of $s$ is performed as specified in Section~\ref{bindingActualsToFormals}, -as if \code{\SUPER{}} respectively \code{\SUPER{}.\id} +as if \code{\SUPER} respectively \code{\SUPER.\id} had had the function type of the denoted constructor, %% TODO(eernst): The following is very imprecise, it just serves to remember %% that we must specify how to deal with the type variables in that parameter @@ -3743,7 +3809,8 @@ \subsubsection{Generative Constructors} \LMHash{}% If $k$ is redirecting then its redirect clause has the form -\code{\THIS{}.$g$($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)} +\noindent +\code{\THIS.$g$($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)} where \DefineSymbol{g} identifies another generative constructor of the immediately surrounding class. @@ -3781,7 +3848,7 @@ \subsubsection{Generative Constructors} Any initializing formals declared in $k$'s parameter list are executed in the order they appear in the program text. % In fact, this order is unobservable; this could be done any time -% prior to running the body, since these only effect \THIS{}. +% prior to running the body, since these only effect \THIS. Then, the initializers of $k$'s initializer list are executed to initialize $i$ in the order they appear in the program, as described below (p.\,\pageref{executionOfInitializerLists}). @@ -3822,7 +3889,7 @@ \subsubsection{Generative Constructors} \LMHash{}% During the execution of a generative constructor to initialize an instance \DefineSymbol{i}, -execution of an initializer of the form \code{\THIS{}.$v$ = $e$} +execution of an initializer of the form \code{\THIS.$v$ = $e$} proceeds as follows: \LMHash{}% @@ -3842,11 +3909,11 @@ \subsubsection{Generative Constructors} Consider a superinitializer \DefineSymbol{s} of the form \noindent -\code{\SUPER{}($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)} +\code{\SUPER($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)} respectively \noindent -\code{\SUPER{}.\id($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}. +\code{\SUPER.\id($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}. \LMHash{}% \BlindDefineSymbol{C, S, u_j, p} @@ -3878,7 +3945,7 @@ \subsubsection{Factories} A \IndexCustom{factory}{constructor!factory} is a constructor prefaced by the built-in identifier (\ref{identifierReference}) -\FACTORY{}. +\FACTORY. \begin{grammar} ::= \gnewline{} @@ -3929,7 +3996,7 @@ \subsubsection{Factories} \begin{grammar} ::= \gnewline{} - \CONST? \FACTORY{} '=' \gnewline{} + \CONST? \FACTORY{} `=' \gnewline{} ::= @@ -4109,7 +4176,7 @@ \subsubsection{Constant Constructors} \LMHash{}% A \IndexCustom{constant constructor}{constructor!constant} may be used to create compile-time constant (\ref{constants}) objects. -A constant constructor is prefixed by the reserved word \CONST{}. +A constant constructor is prefixed by the reserved word \CONST. \begin{grammar} ::= \gnewline{} @@ -4182,7 +4249,7 @@ \subsubsection{Constant Constructors} \commentary{% For instance, if $e$ is \code{a.length} -where \code{a} is a formal argument of $k$ with type \DYNAMIC{}, +where \code{a} is a formal argument of $k$ with type \DYNAMIC, $e$ is potentially constant and can be used in the initializer list of $k$. It is an error to invoke $k$ with an argument of type \code{C} if \code{C} is a class different from \code{String}, @@ -4196,7 +4263,9 @@ \subsection{Static Methods} \LMHash{}% \IndexCustom{Static methods}{method!static} -are functions, other than getters or setters, whose declarations are immediately contained within a class declaration and that are declared \STATIC{}. +are functions, other than getters or setters, +whose declarations 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$. \rationale{% @@ -4244,7 +4313,7 @@ \subsection{Superclasses} \begin{itemize} \item $C$ is \code{Object}, which has no superclass. OR \item Class $C$ is deemed to have an \EXTENDS{} clause of the form -\code{\EXTENDS{} Object}, and the rules above apply. + \code{\EXTENDS{} Object}, and the rules above apply. \end{itemize} \LMHash{}% @@ -4301,7 +4370,7 @@ \subsection{Superclasses} \begin{itemize} \item $S$ is the superclass of $C$, or \item $S$ is a superclass of a class $S'$, -and $S'$ is the superclass of $C$. + and $S'$ is the superclass of $C$. \end{itemize} \LMHash{}% @@ -4414,7 +4483,7 @@ \subsubsection{Inheritance and Overriding} \item A member is abstract if it has no body and is not labeled \EXTERNAL{} (\ref{abstractInstanceMembers}, \ref{externalFunctions}). -\item A class is abstract if{}f it is explicitly labeled \ABSTRACT{}. +\item A class is abstract if{}f it is explicitly labeled \ABSTRACT. \item It is an error if a concrete class does not implement some member of its interface, and there is no non-trivial \code{noSuchMethod} (\ref{classes}). @@ -4499,7 +4568,7 @@ \subsection{Superinterfaces} \LMHash{}% When a generic class $C$ declares a type parameter $X$, it is a compile-time error if $X$ occurs in a non-covariant position -% Could say 'a direct superinterface', but it is easy to see that it is +% Could say `a direct superinterface', but it is easy to see that it is % enough to check direct superinterfaces, and it is then true % for indirect ones as well. in a type which specifies a superinterface of $C$. @@ -4610,7 +4679,7 @@ \section{Interfaces} it omits metadata (\ref{metadata}); and it omits information about whether the member is -\EXTERNAL{}, \ASYNC{}, \ASYNC*, or \SYNC*. +\EXTERNAL, \ASYNC, \ASYNC*, or \SYNC*. It makes no difference whether $D$ is given as explicit syntax or it is induced implicitly, e.g., by a variable declaration. Finally, if $s$ has formal parameters, @@ -4716,11 +4785,11 @@ \section{Interfaces} (\ref{superinterfaces}). \commentary{% -We say that the class interface 'declares' these member signatures, -such that we can say that an interface 'declares' or 'has' a member, +We say that the class interface `declares' these member signatures, +such that we can say that an interface `declares' or `has' a member, just like we do for classes. Note that a member signature $s$ of the interface of class $C$ -may have a parameter $p$ with modifier \COVARIANT{}, +may have a parameter $p$ with modifier \COVARIANT, even though $s$ was derived from a declaration $D$ in $C$ and the parameter corresponding to $p$ in $D$ does not have that modifier. @@ -4827,7 +4896,7 @@ \subsection{Combined Member Signatures} a member \id{} of a class $C$ is well-defined, even in the case where $C$ inherits several different declarations of \id{} -and does not override \id{}. +and does not override \id. In case of failure, it serves to specify the situations where a developer must add a declaration in order to resolve an ambiguity. The member signatures are prioritized in the sense that we will select @@ -4943,7 +5012,7 @@ \subsection{Combined Member Signatures} We can have several such signatures because member signatures can be such that they are not equal, and yet their function types are subtypes of each other. -We need to compute one member signature from \Mall{}, +We need to compute one member signature from \Mall, and we do that by using the ordering of the given interfaces.% } @@ -4968,7 +5037,7 @@ \subsection{Combined Member Signatures} when there exists a $j \in 1 .. q$ such that the parameter corresponding to $p$ (\ref{covariantParameters}) -has the modifier \COVARIANT{}. +has the modifier \COVARIANT. \commentary{% In other words, each parameter in the combined member signature is marked covariant @@ -5088,7 +5157,7 @@ \subsubsection{Inheritance and Overriding} If the above rule would cause multiple member signatures with the same name \id{} to be inherited then exactly one member is inherited, namely -the combined member signature named \id{}, +the combined member signature named \id, from the direct superinterfaces % This is well-defined because $I$ is a class interface. in the textual order that they are declared, @@ -5116,7 +5185,7 @@ \subsubsection{Correct Member Overrides} If $m$ and $m'$ are both methods or both setters: Let $F$ be the function type of $m$ except that the parameter type is the built-in class \code{Object} - for each parameter of $m$ which has the modifier \COVARIANT{}. + for each parameter of $m$ which has the modifier \COVARIANT. Let $F'$ be the function type of $m'$. $F$ must then be a subtype of $F'$. @@ -5202,7 +5271,7 @@ \subsection{Mixin Classes} Let $D$ be a mixin application class declaration of the form \begin{normativeDartCode} -\ABSTRACT? \CLASS{} $N$ = $S$ \WITH{} $M_1$, \ldots{}, $M_n$ \IMPLEMENTS{} $I_1$, \ldots, $I_k$; +\ABSTRACT? \CLASS{} $N$ = $S$ \WITH{} $M_1$, \ldots, $M_n$ \IMPLEMENTS{} $I_1$, \ldots, $I_k$; \end{normativeDartCode} \LMHash{}% @@ -5215,14 +5284,14 @@ \subsection{Mixin Classes} \LMHash{}% The effect of $D$ in library $L$ is to introduce the name $N$ into the scope of $L$, bound to the class (\ref{classes}) defined by the clause -\code{$S$ \WITH{} $M_1$, \ldots{}, $M_n$} +\code{$S$ \WITH{} $M_1$, \ldots, $M_n$} with name $N$, as described below. -If $k > 0$ then the class also implements $I_1$, \ldots{}, $I_k$. -If{}f the class declaration is prefixed by the built-in identifier \ABSTRACT{}, +If $k > 0$ then the class also implements $I_1$, \ldots, $I_k$. +If{}f the class declaration is prefixed by the built-in identifier \ABSTRACT, the class being defined is made an abstract class. \LMHash{}% -A clause of the form \code{$S$ \WITH{} $M_1$, \ldots{}, $M_n$} +A clause of the form \code{$S$ \WITH{} $M_1$, \ldots, $M_n$} with name $N$ defines a class as follows: \LMHash{}% @@ -5233,9 +5302,9 @@ \subsection{Mixin Classes} \LMHash{}% If there is more than one mixin ($n > 1$), then -let $X$ be the class defined by \code{$S$ \WITH{} $M_1$, \ldots{}, $M_{n-1}$} +let $X$ be the class defined by \code{$S$ \WITH{} $M_1$, \ldots, $M_{n-1}$} with name $F$, where $F$ is a fresh name, and make $X$ abstract. -Then \code{$S$ \WITH{} $M_1$, \ldots{}, $M_n$} defines the class yielded +Then \code{$S$ \WITH{} $M_1$, \ldots, $M_n$} defines the class yielded by the mixin application of the mixin of $M_n$ to the class $X$ with name $N$. \LMHash{}% @@ -5249,7 +5318,7 @@ \subsection{Mixin Classes} % to be compile-time errors. \commentary{% -It is an error, for example, if $M$ contains a member declaration $d$ +It is an error, for example, if $M$ contains a member declaration $d$ which overrides a member signature $m$ in the interface of $S$, but which is not a correct override of $m$ (\ref{correctMemberOverrides}).% @@ -5272,7 +5341,7 @@ \subsection{Mixin Declaration} The mixin derived from a class declaration: \begin{normativeDartCode} -\ABSTRACT? \CLASS{} $X$ \IMPLEMENTS{} $I_1$, \ldots{}, $I_k$ \{ +\ABSTRACT? \CLASS{} $X$ \IMPLEMENTS{} $I_1$, \ldots, $I_k$ \{ \metavar{members} \} \end{normativeDartCode} @@ -5297,7 +5366,7 @@ \subsection{Mixin Declaration} It is a compile-time error to declare a constructor in a mixin-declaration. \LMHash{}% -A mixin declaration with no \code{\ON{}} clause is equivalent +A mixin declaration with no \code{\ON} clause is equivalent to one with the clause \code{\ON{} Object}. \LMHash{}% @@ -5326,7 +5395,7 @@ \subsection{Mixin Declaration} Let $M_S$ be the interface declared by the class declaration \begin{normativeDartCode} -\ABSTRACT{} \CLASS{} $M_{super}$<$P_1$, \ldots{}, $P_m$> \IMPLEMENTS{} $T_1$, $\dots{}$, $T_n$ \{\} +\ABSTRACT{} \CLASS{} $M_{super}$<$P_1$, \ldots, $P_m$> \IMPLEMENTS{} $T_1$, $\dots{}$, $T_n$ \{\} \end{normativeDartCode} \noindent @@ -5370,9 +5439,9 @@ \subsection{Mixin Declaration} \LMHash{}% The mixin declaration $M$ introduces a mixin -with the \NoIndex{required superinterface}s $T_1$, \ldots{}, $T_n$, +with the \NoIndex{required superinterface}s $T_1$, \ldots, $T_n$, the \NoIndex{combined superinterface} $M_S$, -\NoIndex{implemented interface}s $I_1$, \ldots{}, $I_k$ +\NoIndex{implemented interface}s $I_1$, \ldots, $I_k$ and the instance members declared in $M$ as \Index{mixin member declarations}. @@ -5386,7 +5455,7 @@ \subsection{Mixin Application} Let $S$ be a class, $M$ be a mixin with \NoIndex{required superinterface}s $T_1$, \ldots, $T_n$, \NoIndex{combined superinterface} $M_S$, -\NoIndex{implemented interfaces} $I_1$, \ldots{}, $I_k$ and +\NoIndex{implemented interfaces} $I_1$, \ldots, $I_k$ and \metavar{members} as \NoIndex{mixin member declarations}, and let $N$ be a name. @@ -5431,7 +5500,7 @@ \subsection{Mixin Application} \noindent where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$, which denote the superclass, by $N$, and $\SUPER_q$ is obtained from $S_q$ by -replacing occurrences of $S_N$ which denote the superclass by \SUPER{}. +replacing occurrences of $S_N$ which denote the superclass by \SUPER. If $S_q$ is a generative const constructor, and $C$ does not declare any instance variables, $C_q$ is also a const constructor. @@ -5450,7 +5519,7 @@ \subsection{Mixin Application} where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$, which denote the superclass, by $N$, $\SUPER_q$ is obtained from $S_q$ by replacing occurrences of $S_N$ -which denote the superclass by \SUPER{}, +which denote the superclass by \SUPER, and $d'_i$, $i \in 1..p$, is a constant expression evaluating to the same value as $d_i$. If $S_q$ is a generative const constructor, and $MC$ does not declare any @@ -5471,7 +5540,7 @@ \subsection{Mixin Application} where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$ which denote the superclass by $N$, $\SUPER_q$ is obtained from $S_q$ by replacing occurrences of $S_N$ -which denote the superclass by \SUPER{}, +which denote the superclass by \SUPER, and $d'_i$, $i \in 1..n$, is a constant expression evaluating to the same value as $d_i$. If $S_q$ is a generative const constructor, and $M$ does not declare any @@ -5580,7 +5649,7 @@ \section{Extensions} an \ON{} type $T$ (specifying the type of receiver) and a set of members. If $e$ is an expression whose static type is $T$ and \code{foo()} is a member declared by \code{E}, -\code{$e$.foo()} may invoke said member with the value of $e$ bound to \THIS{}. +\code{$e$.foo()} may invoke said member with the value of $e$ bound to \THIS. An explicitly resolved form \code{E($e$).foo()} is available, such that \code{E.foo} can be invoked even in the case where \code{$e$.foo()} would invoke some other function @@ -6202,7 +6271,7 @@ \subsection{Static analysis of Members of an Extension} \LMHash{}% A compile-time error occurs if the body of an extension member -contains \SUPER{}. +contains \SUPER. \commentary{% A lexical lookup in an extension $E$ may yield @@ -6219,7 +6288,7 @@ \subsection{Static analysis of Members of an Extension} This is the only situation where implicit invocation of an extension member with basename \id{} can succeed even if the interface of the receiver has -a member with basename \id{}. +a member with basename \id. % On the other hand, it is consistent with the general property of Dart that lexically enclosing declarations shadow other declarations, e.g., @@ -6332,7 +6401,7 @@ \subsection{Extension Method Closurization} \quad.\id<\List{X}{1}{s}>($\List{p}{1}{n},\ p_{n+1}$: $p_{n+1}, \ldots,\ p_{n+k}$: $p_{n+k}$); \end{normativeDartCode} where \id{} declares type parameters -\TypeParametersStd{}, +\TypeParametersStd, required parameters \List{p}{1}{n}, and named parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k}, using \code{null} for parameters whose default value is not specified. @@ -6343,7 +6412,7 @@ \subsection{Extension Method Closurization} \quad$E$<\List{S}{1}{m}>($u$).\id<\List{X}{1}{s}>(\List{p}{1}{n+k}); \end{normativeDartCode} where \id{} declares type parameters -\TypeParametersStd{}, +\TypeParametersStd, required parameters \List{p}{1}{n}, and optional positional parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k}, @@ -6442,7 +6511,7 @@ \subsection{The \CALL{} Member of an Extension} \commentary{% E.g., \code{$e$()} is treated as \code{$e$.call()} -when the static type of $e$ is a non-function that has a method named 'call'. +when the static type of $e$ is a non-function that has a method named \CALL. Here is an example where the \CALL{} method comes from an extension:% } @@ -6520,7 +6589,7 @@ \subsection{The \CALL{} Member of an Extension} \LMHash{}% It is a compile-time error unless $i'$ is an implicit invocation of -an extension instance method named \CALL{}. +an extension instance method named \CALL. \commentary{% In particular, $i'$ cannot be an invocation of an extension getter @@ -6557,7 +6626,8 @@ \section{Enums} \LMLabel{enums} \LMHash{}% -An \Index{enumerated type}, or \Index{enum}, is used to represent a fixed number of constant values. +An \Index{enumerated type}, or \Index{enum}, is used to represent +a fixed number of constant values. \begin{grammar} ::= \ENUM{} @@ -6574,7 +6644,7 @@ \section{Enums} \begin{normativeDartCode} $m$ \CLASS{} $E$ \{ \ \ \FINAL{} int index; -\ \ \CONST{} $E$(\THIS{}.index); +\ \ \CONST{} $E$(\THIS.index); \ \ $m_0$ \STATIC{} \CONST{} $E$ $\id_0$ = \CONST{} $E$(0); \ \ $\ldots$ \ \ $m_{n-1}$ \STATIC{} \CONST{} $E$ $\id_{n-1}$ = const $E$(n - 1); @@ -6622,8 +6692,10 @@ \section{Generics} A \IndexCustom{generic class declaration}{class declaration!generic} introduces a generic class into the library scope of the current library. A \IndexCustom{generic class}{class!generic} -is a mapping that accepts a list of actual type arguments and maps them to a class. -Consider a generic class declaration $G$ named $C$ with formal type parameter declarations +is a mapping that accepts a list of actual type arguments +and maps them to a class. +Consider a generic class declaration $G$ named $C$ +with formal type parameter declarations $X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$, and a parameterized type $T$ of the form \code{$C$<$T_1, \ldots,\ T_l$>}. @@ -6633,8 +6705,12 @@ \section{Generics} (\ref{superBoundedTypes}). \LMHash{}% -Otherwise, said parameterized type \code{$C$<$T_1, \ldots,\ T_m$>} denotes an application of the generic class declared by $G$ to the type arguments $T_1, \ldots, T_m$. -This yields a class $C'$ whose members are equivalent to those of a class declaration which is obtained from the declaration $G$ by replacing each occurrence of $X_j$ by $T_j$. +Otherwise, said parameterized type \code{$C$<$T_1, \ldots,\ T_m$>} denotes +an application of the generic class declared by $G$ to the type arguments +$T_1, \ldots, T_m$. +This yields a class $C'$ whose members are equivalent to those of +a class declaration which is obtained from the declaration $G$ by replacing +each occurrence of $X_j$ by $T_j$. \commentary{% Other properties of $C'$ such as the subtype relationships @@ -6659,7 +6735,8 @@ \section{Generics} \LMHash{}% Consider a function invocation expression of the form \code{f<$T_1, \ldots,\ T_l$>(\ldots)}, -where the static type of \code{f} is a generic function type with formal type parameters +where the static type of \code{f} is a generic function type +with formal type parameters $X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$. It is a compile-time error if $m \not= l$. It is a compile-time error if there exists a $j$ @@ -6680,7 +6757,8 @@ \section{Generics} \end{grammar} \LMHash{}% -A type parameter $T$ may be suffixed with an \EXTENDS{} clause that specifies the \Index{upper bound} for $T$. +A type parameter $T$ may be suffixed with an \EXTENDS{} clause +that specifies the \Index{upper bound} for $T$. If no \EXTENDS{} clause is present, the upper bound is \code{Object}. It is a compile-time error if a type parameter is a supertype of its upper bound when that upper bound is itself a type variable. @@ -6694,9 +6772,11 @@ \section{Generics} \LMHash{}% Type parameters are declared in the type parameter scope of a class or function. -The type parameters of a generic $G$ are in scope in the bounds of all of the type parameters of $G$. +The type parameters of a generic $G$ are in scope in +the bounds of all of the type 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 exist) and in the body of $G$. +the \EXTENDS{} and \IMPLEMENTS{} clauses of $G$ (if these exist) +and in the body of $G$. \commentary{% However, a type parameter of a generic class @@ -7235,7 +7315,8 @@ \subsubsection{Auxiliary Concepts for Instantiation to Bound} \LMLabel{auxiliaryConceptsForInstantiationToBound} \LMHash{}% -Before we specify instantiation to bound we need to define two auxiliary concepts. +Before we specify instantiation to bound +we need to define two auxiliary concepts. Let $T$ be a raw type. A type $S$ then \IndexCustom{raw-depends on}{raw-depends on!type} @@ -7439,7 +7520,7 @@ \subsubsection{The Instantiation to Bound Algorithm} $X_j \TransitivelyDepends X_j$ (\commentary{that is, if the dependency graph has a cycle}) let \List{M}{1}{p} be the strongly connected components (SCCs) - with respect to \Depends{}. + with respect to \Depends. \commentary{% That is, the maximal subsets of \List{X}{1}{k} where every pair of variables in each subset @@ -7493,7 +7574,8 @@ \subsubsection{The Instantiation to Bound Algorithm} a raw type denotes a supertype of all the expressible regular-bounded types. We could easily have made every instantiation to bound an error -when applied to a type where invariance occurs anywhere during the run of the algorithm. +when applied to a type where invariance occurs anywhere +during the run of the algorithm. However, there are a number of cases where this choice produces a usable type, and we decided that it is not helpful to outlaw such cases.% } @@ -7610,7 +7692,8 @@ \section{Metadata} \LMLabel{metadata} \LMHash{}% -Dart supports metadata which is used to attach user defined annotations to program structures. +Dart supports metadata which is used to attach +user defined annotations to program structures. \begin{grammar} ::= (`@' )* @@ -7728,7 +7811,8 @@ \section{Expressions} \end{grammar} \LMHash{}% -An expression $e$ may always be enclosed in parentheses, but this never has any semantic effect on $e$. +An expression $e$ may always be enclosed in parentheses, +but this never has any semantic effect on $e$. \commentary{% However, it may have an effect on the surrounding expression. @@ -7779,22 +7863,30 @@ \subsection{Object Identity} \LMLabel{objectIdentity} \LMHash{}% -The predefined Dart function \code{identical()} is defined such that \code{identical($c_1$, $c_2$)} if{}f: +The predefined Dart function \code{identical()} +is defined such that \code{identical($c_1$, $c_2$)} if{}f: \begin{itemize} -\item $c_1$ evaluates to either the null object (\ref{null}) or an instance of \code{bool} and \code{$c_1$ == $c_2$}, OR +\item $c_1$ evaluates to either the null object (\ref{null}) + or an instance of \code{bool} and \code{$c_1$ == $c_2$}, OR \item $c_1$ and $c_2$ are instances of \code{int} and \code{$c_1$ == $c_2$}, OR \item $c_1$ and $c_2$ are constant strings and \code{$c_1$ == $c_2$}, OR -\item $c_1$ and $c_2$ are instances of \code{double} and one of the following holds: +\item $c_1$ and $c_2$ are instances of \code{double} + and one of the following holds: \begin{itemize} \item $c_1$ and $c_2$ are non-zero and \code{$c_1$ == $c_2$}. \item Both $c_1$ and $c_2$ are $+0.0$. \item Both $c_1$ and $c_2$ are $-0.0$. - \item Both $c_1$ and $c_2$ represent a NaN value with the same underlying bit pattern. + \item Both $c_1$ and $c_2$ represent a NaN value + with the same underlying bit pattern. \end{itemize} OR -\item $c_1$ and $c_2$ are constant lists that are defined to be identical in the specification of literal list expressions (\ref{lists}), OR -\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 -\item $c_1$ and $c_2$ are constant objects of the same class $C$ and the value of each instance variable of $c_1$ is identical to the value of the corresponding instance variable of $c_2$. OR +\item $c_1$ and $c_2$ are constant lists that are defined to be identical + in the specification of literal list expressions (\ref{lists}), OR +\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 +\item $c_1$ and $c_2$ are constant objects of the same class $C$ + and the value of each instance variable of $c_1$ is identical to + the value of the corresponding instance variable of $c_2$. OR \item $c_1$ and $c_2$ are the same object. \end{itemize} @@ -7859,10 +7951,10 @@ \subsection{Constants} \item A literal string (\ref{strings}) with string interpolations (\ref{stringInterpolation}) - with expressions $e_1$, \ldots{}, $e_n$ is a potentially constant expression - if $e_1$, \ldots{}, $e_n$ are potentially constant expressions. + with expressions $e_1$, \ldots, $e_n$ is a potentially constant expression + if $e_1$, \ldots, $e_n$ are potentially constant expressions. The literal is further a constant expression - if $e_1$, \ldots{}, $e_n$ are constant expressions + if $e_1$, \ldots, $e_n$ are constant expressions evaluating to instances of \code{int}, \code{double}, \code{String}, \code{bool}, or \code{Null}. \commentary{% @@ -7950,8 +8042,8 @@ \subsection{Constants} \item A constant list literal (\ref{lists}), - \code{\CONST{} <$T$>[$e_1$, \ldots{}, $e_n$]}, or - \code{<$T$>[$e_1$, \ldots{}, $e_n$]} + \code{\CONST{} <$T$>[$e_1$, \ldots, $e_n$]}, or + \code{<$T$>[$e_1$, \ldots, $e_n$]} that occurs in a constant context, is a potentially constant expression if $T$ is a constant type expression, and $e_1$, \ldots{} , $e_n$ are constant expressions. @@ -7960,8 +8052,8 @@ \subsection{Constants} \item A constant set literal (\ref{sets}), - \code{\CONST{} <$T$>\{$e_1$, \ldots{}, $e_n$\}}, or - \code{<$T$>\{$e_1$, \ldots{}, $e_n$\}} + \code{\CONST{} <$T$>\{$e_1$, \ldots, $e_n$\}}, or + \code{<$T$>\{$e_1$, \ldots, $e_n$\}} that occurs in a constant context, is a potentially constant expression if $T$ is a constant type expression, @@ -7971,8 +8063,8 @@ \subsection{Constants} \item A constant map literal (\ref{maps}), - \code{\CONST{} <$K$, $V$>\{$k_1$: $v_1$, \ldots{}, $k_n$: $v_n$\}}, or - \code{<$K$, $V$>\{$k_1$: $v_1$, \ldots{}, $k_n$: $v_n$\}} + \code{\CONST{} <$K$, $V$>\{$k_1$: $v_1$, \ldots, $k_n$: $v_n$\}}, or + \code{<$K$, $V$>\{$k_1$: $v_1$, \ldots, $k_n$: $v_n$\}} that occurs in a constant context, is a potentially constant expression. It is further a constant expression @@ -8020,7 +8112,7 @@ \subsection{Constants} are both potentially constant expressions. It is further constant if $e_1$ is a constant expression and either \begin{enumerate} - \item $e_1$ evaluates to \FALSE{}, or + \item $e_1$ evaluates to \FALSE, or \item $e_1$ evaluates to \TRUE{} and $e_2$ is a constant expression that evaluates to an instance of type \code{bool}. \end{enumerate} @@ -8031,7 +8123,7 @@ \subsection{Constants} are both potentially constant expressions. It is further constant if $e_1$ is a constant expression and either \begin{enumerate} - \item $e_1$ evaluates to \TRUE{}, or + \item $e_1$ evaluates to \TRUE, or \item $e_1$ evaluates to \FALSE{} and $e_2$ is a constant expression that evaluates to an instance of type \code{bool}. \end{enumerate} @@ -8146,7 +8238,7 @@ \subsection{Constants} that is not qualified by a deferred prefix, optionally followed by type arguments of the form \code{<$T_1$,\ \ldots,\ $T_n$>} - where $T_1$, \ldots{}, $T_n$ are constant type expressions. + where $T_1$, \ldots, $T_n$ are constant type expressions. \item A type of the form \code{FutureOr<$T$>} where $T$ is a constant type expression. @@ -8161,9 +8253,9 @@ \subsection{Constants} and where $R$, \metavar{typeParameters} and \metavar{argumentTypes} (if present) contain only constant type expressions. \item - The type \VOID{}. + The type \VOID. \item - The type \DYNAMIC{}. + The type \DYNAMIC. \end{itemize} % Being potentially constant is entirely structural, not type based, @@ -8235,7 +8327,7 @@ \subsubsection{Further Remarks on Constants and Potential Constants} \\ \CLASS{} K \{ m1() \{ - \VAR{} z = \FALSE{}; + \VAR{} z = \FALSE; \IF{} (z) \{ \RETURN{} x; \} \ELSE{} \{ \RETURN{} 2; \} \} @@ -8269,10 +8361,12 @@ \subsubsection{Further Remarks on Constants and Potential Constants} } \rationale{% -The treatment of \code{\NULL{}} merits some discussion. +The treatment of \code{\NULL} merits some discussion. Consider \code{\NULL{} + 2}. This expression always causes an error. -We could have chosen not to treat it as a constant expression (and in general, not to allow \code{\NULL{}} as a subexpression of numeric or boolean constant expressions). +We could have chosen not to treat it as a constant expression +(and in general, not to allow \code{\NULL} as +a subexpression of numeric or boolean constant expressions). There are two arguments for including it: First, it is constant so we \emph{can} evaluate it at compile time. Second, it seems more useful to give @@ -8361,11 +8455,11 @@ \subsubsection{Further Remarks on Constants and Potential Constants} \rationale{% All of the illegal constructors of \code{D} above -could not be sensibly invoked via \NEW{}, +could not be sensibly invoked via \NEW, because an expression that must be constant cannot depend on a formal parameter, which may or may not be constant. In contrast, the legal examples make sense regardless of -whether the constructor is invoked via \CONST{} or via \NEW{}. +whether the constructor is invoked via \CONST{} or via \NEW. Careful readers will of course worry about cases where the actual arguments to \code{C()} are constants, but are not numeric. @@ -8386,7 +8480,7 @@ \subsubsection{Constant Contexts} % We avoid the circularity "constant context depends on constant list literal, % etc., which depends on constant context" by mentioning the \CONST{} modifier % explicitly here. So 'constant context' is consistently a lower-level concept -% based on syntax, and 'constant X expressions' (like 'constant list literal') +% based on syntax, and `constant X expressions' (like `constant list literal') % are built on top of this. \begin{itemize} @@ -8432,8 +8526,10 @@ \subsection{Null} % The following can be a consequence of the declaration of `Null`, % but we don't spell that out, we just require that it is an error. Attempting to instantiate \code{Null} causes a compile-time error. -It is a compile-time error for a class to extend, mix in or implement \code{Null}. -The \code{Null} class extends the \code{Object} class and declares no methods except those also declared by \code{Object}. +It is a compile-time error for a class to extend, mix in or implement +\code{Null}. +The \code{Null} class extends the \code{Object} class +and declares no methods except those also declared by \code{Object}. In particular, the \code{Null} class does not override the \lit{==} operator inherited from the \code{Object} class. @@ -8446,7 +8542,8 @@ \subsection{Numbers} \LMHash{}% A \IndexCustom{numeric literal}{literal!numeric} -is either a decimal or hexadecimal numeral representing an integer value, or a decimal double representation. +is either a decimal or hexadecimal numeral representing an integer value, +or a decimal double representation. \begin{grammar} ::= @@ -8497,7 +8594,9 @@ \subsection{Numbers} \LMHash{}% A numeric literal that is not an integer literal is a \IndexCustom{double literal}{literal!double}. -\commentary{A double literal always contains either a decimal point or an exponent part.} +\commentary{% +A double literal always contains either a decimal point or an exponent part.% +} The static type of a double literal is \code{double}. \LMHash{}% @@ -8548,12 +8647,17 @@ \subsection{Numbers} } \LMHash{}% -It is a compile-time error for a class to extend, mix in or implement \code{int}. -It is a compile-time error for a class to extend, mix in or implement \code{double}. -It is a compile-time error for any class other than \code{int} and \code{double} to extend, mix in or implement \code{num}. +It is a compile-time error for a class to extend, mix in or implement +\code{int}. +It is a compile-time error for a class to extend, mix in or implement +\code{double}. +It is a compile-time error for any class +other than \code{int} and \code{double} to extend, mix in or implement +\code{num}. \LMHash{}% -The instances of \code{int} and \code{double} all override the \lit{==} operator inherited from the \code{Object} class. +The instances of \code{int} and \code{double} all override +the \lit{==} operator inherited from the \code{Object} class. \subsection{Booleans} @@ -8583,7 +8687,8 @@ \subsection{Booleans} the \code{Object} class. \LMHash{}% -Invoking the getter \code{runtimeType} on a boolean value returns the \code{Type} object that is the value of the expression \code{bool}. +Invoking the getter \code{runtimeType} on a boolean value returns +the \code{Type} object that is the value of the expression \code{bool}. The static type of a boolean literal is \code{bool}. @@ -8618,7 +8723,8 @@ \subsection{Strings} ( )* \gnewline{} - ::= `r' `\sq' (\gtilde(`\sq' | `\\r' | `\\n'))* `\sq' + ::= + `r' `\sq' (\gtilde(`\sq' | `\\r' | `\\n'))* `\sq' \alt `r' `"' (\gtilde(`"' | `\\r' | `\\n'))* `"' ::= \gtilde(`\\' | `\sq' | `"' | `$' | `\\r' | `\\n') @@ -8656,13 +8762,14 @@ \subsection{Strings} \end{grammar} \LMHash{}% -A single line string is delimited by either matching single quotes or matching double quotes. +A single line string is delimited by +either matching single quotes or matching double quotes. \commentary{% -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''.% +Hence, \code{'abc'} and \code{"abc"} are both legal strings, +as are \code{'He said "To be or not to be" did he not?'} and +\code{"He said 'To be or not to be' didn't he?"}. +However, \code{"This'} is not a valid string, nor is \code{'this"}.% } \commentary{% @@ -8873,7 +8980,7 @@ \subsection{Strings} \item \lit{\$} indicating the beginning of an interpolated expression. \item - { % We need a definition for $k$ in order to be able to use it in \syntax{}. + { % We need a definition for $k$ in order to be able to use it in \syntax. \def\k{$k$} Otherwise, \syntax{`\\\k'} indicates the character \k{} for any \k{} not in \syntax{$\{$`n', `r', `f', `b', `t', `v', `x', `u'$\}$}. @@ -9080,7 +9187,8 @@ \subsection{Collection Literals} \LMHash{}% The subsections of this section are concerned with mechanisms that are common to all kinds of collection literals -(\ref{collectionLiteralTypePromotion}, \ref{collectionLiteralElementEvaluation}), +(\ref{collectionLiteralTypePromotion}, +\ref{collectionLiteralElementEvaluation}), followed by a specification of list literals (\ref{listLiteralInference}, \ref{lists}), followed by a specification of how to disambiguate and infer types @@ -9283,8 +9391,8 @@ \subsection{Collection Literals} %% may not be assigned to the for-in variable's type." %% Covered by the same text again. %% -%% - "The type of the stream expression in an asynchronous \AWAIT{} for-in element -%% may not be assigned to \code{Stream<$T$>} for any type $T$. +%% - "The type of the stream expression in an asynchronous \AWAIT{} for-in +%% element may not be assigned to \code{Stream<$T$>} for any type $T$. %% Otherwise, the \Index{stream type} of the stream is $T$". %% Same text again (the `forElement` text includes both await for and for). %% @@ -9498,7 +9606,8 @@ \subsubsection{Collection Literal Element Evaluation} \begin{itemize} \item - When \metavar{target} is a list or a set and $T_{\metavar{spread}}$ implements + When \metavar{target} is a list or a set + and $T_{\metavar{spread}}$ implements (\ref{interfaceSuperinterfaces}) \code{Iterable}, the following code is executed in the context where $\ell$ occurs, @@ -9510,7 +9619,7 @@ \subsubsection{Collection Literal Element Evaluation} \vspace{-2ex}\begin{minipage}[t]{\textwidth} \begin{normativeDartCode} $S_{\metavar{spread}}$ spread = $o_{\metavar{spread}}$; -\VAR{} $s$ = \LiteralSequence{}; +\VAR{} $s$ = \LiteralSequence; \FOR{} (\VAR{} v \IN{} spread) \{ Value value = v; $s := s + \LiteralSequence{\code{value}}$; @@ -9542,7 +9651,7 @@ \subsubsection{Collection Literal Element Evaluation} \vspace{-2ex}\begin{minipage}[t]{\textwidth} \begin{normativeDartCode} $S_{\metavar{spread}}$ spread = $o_{\metavar{spread}}$; -\VAR{} $s$ = \LiteralSequence{}; +\VAR{} $s$ = \LiteralSequence; \FOR{} (\VAR{} v \IN{} spread) \{ Key key = v.key; Value value = v.value; @@ -9552,7 +9661,7 @@ \subsubsection{Collection Literal Element Evaluation} \end{normativeDartCode} \end{minipage} - % Will not change with nnbd: `spread` type arguments could be \DYNAMIC{}. + % Will not change with nnbd: `spread` type arguments could be \DYNAMIC. It is allowed for an implementation to delay the dynamic errors that occur if the given \code{key} does not have the type \code{Key}, or the given \code{value} does not have the type \code{Value}, @@ -9563,7 +9672,7 @@ \subsubsection{Collection Literal Element Evaluation} \commentary{% This occurs when the target is an iterable respectively a map, and the spread is not, which is possible for - a spread whose static type is \DYNAMIC{}.% + a spread whose static type is \DYNAMIC.% } \end{itemize} \end{enumerate} @@ -9581,7 +9690,8 @@ \subsubsection{Collection Literal Element Evaluation} (\ref{interfaceSuperinterfaces}) \code{List}, \code{Queue}, or \code{Set}, an implementation may choose to call \code{length} on the object. -If $o_{\metavar{spread}}$ is an object whose dynamic type implements \code{List}, +If $o_{\metavar{spread}}$ is an object +whose dynamic type implements \code{List}, an implementation may choose to call operator \lit{[]} in order to access elements from the list. If it does so, it will only pass indices @@ -9611,7 +9721,7 @@ \subsubsection{Collection Literal Element Evaluation} $\EvaluateElement{\ell} := \EvaluateElement{\ell_2}$, and if $\ell_2$ is not present then $\EvaluateElement{\ell} := \LiteralSequence{}$. -% $o_b$ can have type \DYNAMIC{}. +% $o_b$ can have type \DYNAMIC. If $o_b$ is neither \TRUE{} nor \FALSE{} then a dynamic error occurs. \EndCase @@ -9627,7 +9737,7 @@ \subsubsection{Collection Literal Element Evaluation} \vspace{-2ex}\begin{minipage}[t]{\textwidth} \begin{normativeDartCode} -\VAR{} $s$ = \LiteralSequence{}; +\VAR{} $s$ = \LiteralSequence; \AWAIT? \FOR{} ($P$) \{ $s := s + \EvaluateElement{\ell_1}$; \} @@ -9712,7 +9822,7 @@ \subsubsection{List Literal Inference} the inferred element type of $\ell$ is the type argument of $S$ at \code{Iterable}. \item - If $S$ is \DYNAMIC{}, + If $S$ is \DYNAMIC, the inferred element type of $\ell$ is \DYNAMIC. \item If $S$ is \code{Null} and the spread operator is \lit{...?}, @@ -9793,7 +9903,7 @@ \subsubsection{List Literal Inference} the inferred element types of \List{\ell}{1}{n}. \item - %% TODO(eernst): Feature spec says $P$, but how can we know that $P$ is a type? + %% TODO(eernst): Feature spec says $P$, but how do we know $P$ is a type? Otherwise, the inferred element type for \metavar{list} is $T$, where $T$ is determined by downwards inference. @@ -9840,7 +9950,8 @@ \subsubsection{Lists} The number of objects 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. +A non-empty list has the index set $\{0, \ldots, n - 1\}$ +where $n$ is the size of the list. It is a dynamic error to attempt to access a list using an index that is not a member of its set of indices. @@ -9979,12 +10090,12 @@ \subsubsection{Set and Map Literal Disambiguation} Let $e$ be a \synt{setOrMapLiteral} with leaf elements $\cal L$ and context type $C$. If $C$ is \FreeContext{} then let $S$ be undefined. -%% TODO(eernst): Define 'greatest closure' of a context type -%% when we define 'context type'. +%% TODO(eernst): Define `greatest closure' of a context type +%% when we define `context type'. Otherwise let $S$ be the greatest closure of \futureOrBase{C} (\ref{typeFutureOr}). -%% TODO(eernst): Delete when 'context type', 'greatest closure' are defined. +%% TODO(eernst): Delete when `context type', `greatest closure' are defined. \commentary{% A future version of this document will specify context types. The basic intuition is that a @@ -10028,7 +10139,8 @@ \subsubsection{Set and Map Literal Disambiguation} $e$ is a map literal. \item When ${\cal L} \not= \emptyset$ (\commentary{that is, $e$ has leaf elements}): - If $\cal L$ contains a \synt{mapElement} as well as an \synt{expressionElement}, + If $\cal L$ contains a \synt{mapElement} + as well as an \synt{expressionElement}, a compile-time error occurs. Otherwise, if $\cal L$ contains an \synt{expressionElement}, $e$ is a set literal. @@ -10083,7 +10195,7 @@ \subsubsection{Set and Map Literal Inference} If $e$ has an element type then it may be a set, and if it has a key and value type pair then it may be a map. % -However, if the literal $e$ contains a spread element of type \DYNAMIC{}, +However, if the literal $e$ contains a spread element of type \DYNAMIC, that element cannot be used to determine whether $e$ is a set or a map. The ambiguity is represented as having \emph{both} an element type and a key and value type pair. @@ -10202,7 +10314,7 @@ \subsubsection{Set and Map Literal Inference} \Case{Map element} In this case $\ell$ is a pair of expressions \code{$e_k$:\,$e_v$}. % -If $P$ is \FreeContext{}, +If $P$ is \FreeContext, the inferred key and value type pair of $\ell$ is $(K, V)$, where $K$ and $V$ is the inferred type of $e_k$ respectively $e_v$, @@ -10288,8 +10400,8 @@ \subsubsection{Set and Map Literal Inference} the constraint $S <: \code{Iterable<$X$>}$.% } \item - If $S$ is \DYNAMIC{}, - the inferred element type of $\ell$ is \DYNAMIC{}. + If $S$ is \DYNAMIC, + the inferred element type of $\ell$ is \DYNAMIC. \item If $S$ is \code{Null} and the spread operator is \lit{...?}, the inferred element type of $\ell$ is \code{Null}. @@ -10436,7 +10548,7 @@ \subsubsection{Set and Map Literal Inference} where $T$ is the least upper bound of the inferred element types of the elements. \item - %% TODO(eernst): Feature spec says $P$, but how can we know that $P$ is a type? + %% TODO(eernst): Feature spec says $P$, but how do we know $P$ is a type? Otherwise, the static type of \metavar{collection} is $T$ where $T$ is determined by downwards inference. @@ -10473,7 +10585,8 @@ \subsubsection{Set and Map Literal Inference} The static type of \metavar{collection} is then \code{Map<$K$,\,\,$V$>}. \item Otherwise, \metavar{collection} is still ambiguous, - the downwards context for the elements of \metavar{collection} is \FreeContext{}, + the downwards context for the elements of \metavar{collection} + is \FreeContext, and the disambiguation is done using the immediate elements of \metavar{collection} as follows: @@ -10578,7 +10691,8 @@ \subsubsection{Sets} but we specify only the minimal set of requirements which are used by the language itself.% -Note that an implementation may require consistent definitions of several members +Note that an implementation may require +consistent definitions of several members of a class implementing \code{Set} in order to work correctly. For instance, there may be a getter \code{hashCode} which is required to have a behavior which is in some sense consistent with operator \lit{==}. @@ -10773,7 +10887,8 @@ \subsubsection{Maps} but we specify only the minimal set of requirements which are used by the language itself. -Note that an implementation may require consistent definitions of several members +Note that an implementation may require +consistent definitions of several members of a class implementing \code{Map} in order to work correctly. For instance, there may be a getter \code{hashCode} which is required to have a behavior which is in some sense consistent with operator \lit{==}. @@ -10781,7 +10896,7 @@ \subsubsection{Maps} } \LMHash{}% -If a map literal $e$ begins with the reserved word \CONST{}, +If a map literal $e$ begins with the reserved word \CONST, or if $e$ occurs in a constant context (\ref{constantContexts}), it is a @@ -10905,7 +11020,9 @@ \subsection{Throw} \end{grammar} \LMHash{}% -Evaluation of a throw expression of the form \code{\THROW{} $e$;} proceeds as follows: +Evaluation of a throw expression of the form +\code{\THROW{} $e$;} +proceeds as follows: \LMHash{}% The expression $e$ is evaluated to an object $v$ @@ -10985,24 +11102,26 @@ \subsection{Function Expressions} \item If $T$ is \code{FutureOr<$S$>} for some $S$ then $\flatten{T} = S$. \item Otherwise if -\code{$T <:$ Future} -then let $S$ be a type such that -\code{$T <:$ Future<$S$>} -and for all $R$, if -\code{$T <:$ Future<$R$>} -then $S <: R$. + \code{$T <:$ Future} + then let $S$ be a type such that + \code{$T <:$ Future<$S$>} + and for all $R$, if + \code{$T <:$ Future<$R$>} + then $S <: R$. -\rationale{% -This ensures that -\code{Future<$S$>} -is the most specific generic instantiation of \code{Future} that is a supertype of $T$. -%% TODO[class-interfaces]: When we have finished the specification of class -%% interface computations we may have the following property, but it is not -%% true at this point. Adjust the following by then! -Note that $S$ is well-defined because of the requirements on superinterfaces.% -} + \rationale{% + This ensures that + \code{Future<$S$>} + is the most specific generic instantiation of \code{Future} that is + a supertype of $T$. + %% TODO[class-interfaces]: When we have finished the specification of class + %% interface computations we may have the following property, but it is not + %% true at this point. Adjust the following by then! + Note that $S$ is well-defined because of + the requirements on superinterfaces.% + } -Then $\flatten{T} = S$. + Then $\flatten{T} = S$. \item In any other circumstance, $\flatten{T} = T$. \end{itemize} @@ -11022,7 +11141,7 @@ \subsection{Function Expressions} \FunctionTypePositionalStd{T_0}, \noindent -%% TODO[inference]: The static type of the function literal may come from context. +%% TODO[inference]: The static type of the function literal may be inferred. where $T_0$ is the static type of $e$. \EndCase @@ -11211,7 +11330,7 @@ \subsection{Function Expressions} In all of the above cases, the type argument lists are omitted when $m=0$, and whenever $T_i$ is not specified, $i \in 1 .. n+k$, -it is considered to have been specified as \DYNAMIC{}. +it is considered to have been specified as \DYNAMIC. \LMHash{}% Evaluation of a function literal yields a function object $o$. @@ -11229,7 +11348,8 @@ \subsection{This} \LMLabel{this} \LMHash{}% -The reserved word \THIS{} denotes the target of the current instance member invocation. +The reserved word \THIS{} denotes +the target of the current instance member invocation. \begin{grammar} ::= \THIS{} @@ -11243,7 +11363,10 @@ \subsection{This} } \LMHash{}% -It is a compile-time error if \THIS{} appears, implicitly or explicitly, in a top-level function or variable initializer, in a factory constructor, or in a static method or variable initializer, or in the initializer of an instance variable. +It is a compile-time error if \THIS{} appears, implicitly or explicitly, +in a top-level function or variable initializer, in a factory constructor, +or in a static method or variable initializer, +or in the initializer of an instance variable. \subsection{Instance Creation} @@ -11266,12 +11389,16 @@ \subsection{Instance Creation} It is a compile-time error if the type $T$ in an instance creation expression of one of the forms +\noindent \code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}, +\noindent \code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}, +\noindent \code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}, +\noindent \code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)} \noindent @@ -11291,9 +11418,11 @@ \subsubsection{New} \LMHash{}% Let $e$ be a new expression of the form +\noindent \code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)} or the form +\noindent \code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}. \LMHash{}% @@ -11380,11 +11509,13 @@ \subsubsection{New} \LMHash{}% First, the argument part +\noindent \code{<$U_1, \ldots,\ U_m$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)} \noindent is evaluated, yielding the evaluated actual argument part +\noindent \code{<$u_1, \ldots,\ u_m$>($o_1, \ldots,\ o_n,\ x_{n+1}$: $o_{n+1},\ \ldots,\ x_{n+k}$: $o_{n+k}$)}. \noindent @@ -11414,14 +11545,15 @@ \subsubsection{New} % because $T$ includes the type arguments; but we also provide them % as a binding accessible to the constructor: Otherwise we couldn't % access the type parameters in the initializing expressions of the -% initializer list where there is no access to \THIS{}. +% initializer list where there is no access to \THIS. Then $q$ is executed to initialize $i$ with respect to the bindings that resulted from the evaluation of the argument list, and, if $R$ is a generic class, with its type parameters bound to $u_1, \ldots, u_m$. \LMHash{}% -If execution of $q$ completes normally (\ref{statementCompletion}), $e$ evaluates to $i$. +If execution of $q$ completes normally (\ref{statementCompletion}), +$e$ evaluates to $i$. Otherwise execution of $q$ throws an exception object $x$ and stack trace $t$, and then evaluation of $e$ also throws exception object $x$ and stack trace $t$ (\ref{expressionEvaluation}). @@ -11482,9 +11614,11 @@ \subsubsection{Const} \LMHash{}% Let $e$ be a constant object expression of the form +\noindent \code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)} or the form +\noindent \code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}. \LMHash{}% @@ -11602,13 +11736,15 @@ \subsubsection{Const} \item If during execution of the program, a constant object expression has already evaluated to an instance $j$ of class $R$ with type arguments $U_i, 1 \le i \le m$, then: -\begin{itemize} -\item For each instance variable $f$ of $i$, - let $v_{if}$ be the value of the instance variable $f$ in $i$, and - let $v_{jf}$ be the value of the instance variable $f$ in $j$. - If \code{identical($v_{if}$, $v_{jf}$)} for all instance variables $f$ in $i$ - then the value of $e$ is $j$, otherwise the value of $e$ is $i$. -\end{itemize} + \begin{itemize} + \item For each instance variable $f$ of $i$, + let $v_{if}$ be the value of the instance variable $f$ in $i$, and + let $v_{jf}$ be the value of the instance variable $f$ in $j$. + If \code{identical($v_{if}$, $v_{jf}$)} + for all instance variables $f$ in $i$ + then the value of $e$ is $j$, + otherwise the value of $e$ is $i$. + \end{itemize} \item Otherwise the value of $e$ is $i$. \end{itemize} @@ -11641,7 +11777,7 @@ \subsubsection{Const} \} \\ \CLASS{} IntPair \{ - \CONST{} IntPair(\THIS{}.x, \THIS{}.y); + \CONST{} IntPair(\THIS.x, \THIS.y); \FINAL{} int x; \FINAL{} int y; \OPERATOR *(v) => \NEW{} IntPair(x*v, y*v); @@ -11668,12 +11804,16 @@ \subsection{Spawning an Isolate} \LMLabel{spawningAnIsolate} \LMHash{}% -Spawning an isolate is accomplished via what is syntactically an ordinary method call, -invoking one of the static methods \code{spawnUri} or \code{spawn} defined in the \code{Isolate} class in the library \code{dart:isolate}. -However, such calls have the semantic effect of creating a new isolate with its own memory and thread of control. +Spawning an isolate is accomplished via what is syntactically +an ordinary method call, +invoking one of the static methods \code{spawnUri} or \code{spawn} defined in +the \code{Isolate} class in the library \code{dart:isolate}. +However, such calls have the semantic effect of creating +a new isolate with its own memory and thread of control. \LMHash{}% -An isolate's memory is finite, as is the space available to its thread's call stack. +An isolate's memory is finite, as is the space available to +its thread's call stack. % This error can occur because memory usage is a dynamic property. It is possible for a running isolate to exhaust its memory or stack, resulting in a dynamic error that cannot be effectively caught, @@ -11690,22 +11830,35 @@ \subsection{Function Invocation} \LMHash{}% Function invocation occurs in the following cases: -when a function expression (\ref{functionExpressions}) is invoked (\ref{functionExpressionInvocation}), -when a method (\ref{methodInvocation}), getter (\ref{topLevelGetterInvocation}, \ref{propertyExtraction}) or setter (\ref{assignment}) is invoked, +when a function expression (\ref{functionExpressions}) +is invoked (\ref{functionExpressionInvocation}), +when a method (\ref{methodInvocation}), +getter (\ref{topLevelGetterInvocation}, \ref{propertyExtraction}) +or setter (\ref{assignment}) +is invoked, or when a constructor is invoked -(either via instance creation (\ref{instanceCreation}), constructor redirection (\ref{redirectingGenerativeConstructors}), or super initialization). -The various kinds of function invocation differ as to how the function to be invoked, $f$, is determined, as well as whether \THIS{} (\ref{this}) is bound. +(either via instance creation (\ref{instanceCreation}), +constructor redirection (\ref{redirectingGenerativeConstructors}), +or super initialization). +The various kinds of function invocation differ as to +how the function to be invoked, $f$, is determined, +as well as whether \THIS{} (\ref{this}) is bound. Once $f$ has been determined, -formal type parameters of $f$ are bound to the corresponding actual type arguments, +formal type parameters of $f$ are bound to +the corresponding actual type arguments, and the formal parameters of $f$ are bound to corresponding actual arguments. -When the body of $f$ is executed it will be executed with the aforementioned bindings. +When the body of $f$ is executed it will be executed +with the aforementioned bindings. \LMHash{}% -Executing a body of the form \code{=> $e$} is equivalent to executing a body of the form \code{\{ return $e$; \}}. -Execution a body of the form \code{\ASYNC{} => $e$} is equivalent to executing a body of the form \code{\ASYNC{} \{ return $e$; \}}. +Executing a body of the form \code{=> $e$} is equivalent to executing +a body of the form \code{\{ return $e$; \}}. +Execution a body of the form \code{\ASYNC{} => $e$} is equivalent to executing +a body of the form \code{\ASYNC{} \{ return $e$; \}}. \LMHash{}% -If $f$ is synchronous and is not a generator (\ref{functions}) then execution of the body of $f$ begins immediately. +If $f$ is synchronous and is not a generator (\ref{functions}) then +execution of the body of $f$ begins immediately. If the execution of the body of $f$ returns an object $v$ (\ref{statementCompletion}), the invocation evaluates to $v$. @@ -11716,10 +11869,12 @@ \subsection{Function Invocation} (\ref{expressionEvaluation}). \commentary{% -A complete function body can never break or continue (\ref{statementCompletion}) +A complete function body can never break or continue +(\ref{statementCompletion}) because a \BREAK{} or \CONTINUE{} statement must always occur inside -the statement that is the target of the \BREAK{} or \CONTINUE{}. -This means that a function body can only either complete normally, throw, or return. +the statement that is the target of the \BREAK{} or \CONTINUE. +This means that a function body can only +either complete normally, throw, or return. Completing normally or returning without an object is treated the same as returning with the null object (\ref{null}), so the result of executing a function body can always be used as @@ -11747,7 +11902,9 @@ \subsection{Function Invocation} } \LMHash{}% -The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contract. +The iterable implementation must comply with +the contract of \code{Iterable} and should not +take any steps identified as exceptionally efficient in that contract. \commentary{% The contract explicitly mentions a number of situations @@ -11782,7 +11939,8 @@ \subsection{Function Invocation} \LMHash{}% Each iterator starts a separate computation. -If the \code{\SYNC*} function is impure, the sequence of objects yielded by each iterator may differ. +If the \code{\SYNC*} function is impure, +the sequence of objects yielded by each iterator may differ. \commentary{% One can derive more than one iterator from a given iterable. @@ -11805,14 +11963,19 @@ \subsection{Function Invocation} \commentary{% Two executions of an iterator interact only via state outside the function.% } -% The alternative would be to cache the results of an iterator in the iterable, and check the cache at each \YIELD{}. This would have strange issues as well. The yielded value might differ from the expression in the yield. And it is a potential memory leak as the cache is kept alive by any iterator. +% The alternative would be to cache the results of an iterator in the iterable, +% and check the cache at each \YIELD. This would have strange issues as well. +% The yielded value might differ from the expression in the yield. And it is a +% potential memory leak as the cache is kept alive by any iterator. \LMHash{}% If $f$ is marked \ASYNC{} (\ref{functions}), -then a fresh instance (\ref{generativeConstructors}) $o$ is associated with the invocation, +then a fresh instance (\ref{generativeConstructors}) $o$ +is associated with the invocation, where the dynamic type of $o$ implements \code{Future<$flatten(T)$>}, and $T$ is the actual return type of $f$ (\ref{actualTypes}). -Then the body of $f$ is executed until it either suspends or completes, at which point $o$ is returned. +Then the body of $f$ is executed until it either suspends or completes, +at which point $o$ is returned. \commentary{% The body of $f$ may suspend during the evaluation of an \AWAIT{} expression or execution of an asynchronous \FOR{} loop.% @@ -11849,7 +12012,8 @@ \subsection{Function Invocation} then its cancellation future is completed with the null object (\ref{null}). \item If it throws an exception object $e$ and stack trace $t$: \begin{itemize} - \item If $s$ has been canceled then its cancellation future is completed with error $e$ and stack trace $t$. + \item If $s$ has been canceled then its cancellation future is completed + with error $e$ and stack trace $t$. \item otherwise the error $e$ and stack trace $t$ are emitted by $s$. \end{itemize} \item $s$ is closed. @@ -11906,11 +12070,13 @@ \subsubsection{Actual Argument Lists} \LMHash{}% Let $\argumentList{S}$ be the static argument list type +\noindent \code{($S_1 \ldots,\ S_m,\ S_{m+1}\ y_{m+1} \ldots,\ S_{m+p}\ y_{m+p}$)} \noindent and let $\parameterList{P}$ be the formal parameter list +\noindent \code{($T_1\ x_1 \ldots,\ T_n\ x_n,\ $[$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$])} \noindent @@ -11930,11 +12096,13 @@ \subsubsection{Actual Argument Lists} \LMHash{}% Let $\argumentList{S}$ be the static argument list type +\noindent \code{($S_1 \ldots,\ S_m,\ S_{m+1}\ y_{m+1} \ldots,\ S_{m+p}\ y_{m+p}$)} \noindent and let $\parameterList{P}$ be the formal parameter list +\noindent \code{($T_1\ x_1 \ldots,\ T_n\ x_n,\ $\{$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$\})} \noindent @@ -11969,18 +12137,21 @@ \subsubsection{Actual Argument List Evaluation} \LMLabel{actualArguments} \LMHash{}% -Function invocation involves evaluation of the list of actual arguments to the function, +Function invocation involves evaluation of +the list of actual arguments to the function, and binding of the results to the function's formal parameters. \LMHash{}% -When parsing an argument list, an ambiguity may arise because the same source code could be one generic function invocation, +When parsing an argument list, an ambiguity may arise because +the same source code could be one generic function invocation, and it could be two or more relational expressions and/or shift expressions. -In this situation, the expression is always parsed as a generic function invocation. +In this situation, the expression is always parsed +as a generic function invocation. % Should we specify the precise disambiguation rule here?: -% We have seen 'a', '<', a matching '>', and '(', where -% 'a' is tricky because we can have things like 'new Foo().m<...>(...', -% 'x..y(...).m<...>(...', etc, basically everything that can precede +% We have seen `a`, `<`, a matching `>`, and `(`, where +% `a` is tricky because we can have things like `new Foo().m<...>(...`, +% `x..y(...).m<...>(...`, etc, basically everything that can precede % argumentPart in the grammar. \commentary{% @@ -12008,13 +12179,17 @@ \subsubsection{Actual Argument List Evaluation} \LMHash{}% Evaluation of an actual argument part of the form +\noindent \code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)} - proceeds as follows: \LMHash{}% -The type arguments $A_1, \ldots, A_r$ are evaluated in the order they appear in the program, producing types $t_1, \ldots, t_r$. -The arguments $a_1, \ldots, a_{m+l}$ are evaluated in the order they appear in the program, producing objects $o_1, \ldots, o_{m+l}$. +The type arguments $A_1, \ldots, A_r$ are evaluated +in the order they appear in the program, +producing types $t_1, \ldots, t_r$. +The arguments $a_1, \ldots, a_{m+l}$ are evaluated +in the order they appear in the program, +producing objects $o_1, \ldots, o_{m+l}$. \commentary{% Simply stated, an argument part consisting of $s$ type arguments, @@ -12036,7 +12211,8 @@ \subsubsection{Binding Actuals to Formals} } \LMHash{}% -Consider an invocation $i$ of a function $f$ with an actual argument part of the form +Consider an invocation $i$ of a function $f$ with +an actual argument part of the form \code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)}. \commentary{% @@ -12106,7 +12282,7 @@ \subsubsection{Binding Actuals to Formals} If the static type of $f$ is \DYNAMIC{} bounded or \FUNCTION{} bounded, no further static checks are performed on the invocation $i$ (\commentary{apart from separate static checks on subterms like arguments}), -and the static type of $i$ is \DYNAMIC{}. +and the static type of $i$ is \DYNAMIC. Otherwise, it is a compile-time error if the static type of $f$ is not function-type bounded. @@ -12196,7 +12372,8 @@ \subsubsection{Binding Actuals to Formals} \end{figure} \LMHash{}% -% Type inference is assumed complete, so we must have the correct number of type arguments. +% Type inference is assumed complete, so we must have +% the correct number of type arguments. It is a compile-time error if $r \not= s$. It is a compile-time error if $r = s$ and for some $j \in 1 .. s$, $A_j \not<: [A_1/X_1, \ldots, A_r/X_s]B_j$. @@ -12217,8 +12394,10 @@ \subsubsection{Binding Actuals to Formals} The static type of $i$ is $[A_1/X_1, \ldots, A_r/X_s]S_0$. \LMHash{}% -It is a compile-time error if $T_j$ may not be assigned to $S_j, j \in 1 .. m$. -It is a compile-time error if $T_{m+j}$ may not be assigned to $S_{q_j}, j \in 1 .. l$. +It is a compile-time error if $T_j$ may not be assigned to +$S_j, j \in 1 .. m$. +It is a compile-time error if $T_{m+j}$ may not be assigned to +$S_{q_j}, j \in 1 .. l$. \commentary{% Consider the case where the function invocation in focus here is @@ -12255,11 +12434,13 @@ \subsubsection{Binding Actuals to Formals} \LMHash{}% An evaluated actual argument part +\noindent \code{<$t_1, \ldots,\ t_r$>($o_1, \ldots,\ o_m,\ q_1$: $o_{m+1},\ \ldots,\ q_l$: $o_{m+l}$)} \noindent derived from an actual argument part of the form +\noindent \code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)} \noindent @@ -12345,7 +12526,7 @@ \subsubsection{Unqualified Invocation} \LMHash{}% \Case{Lexical lookup yields a declaration} -Let $D$ be the declaration yielded by the lexical lookup of \id{}. +Let $D$ be the declaration yielded by the lexical lookup of \id. \begin{itemize} \item @@ -12540,7 +12721,8 @@ \subsubsection{Function Expression Invocation} \code{$f$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)} \noindent -is evaluated by binding actuals to formals as specified in Section~\ref{bindingActualsToFormals}, +is evaluated by binding actuals to formals +as specified in Section~\ref{bindingActualsToFormals}, and executing the body of $f$ with those bindings; the returned result is then the result of evaluating $i$. @@ -12554,8 +12736,9 @@ \subsubsection{Function Expression Invocation} \code{$f$.call<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}. \LMHash{}% -Otherwise $o$ has no method named \CALL{}. -A new instance $im$ of the predefined class \code{Invocation} is created, such that: +Otherwise $o$ has no method named \CALL. +A new instance $im$ of the predefined class \code{Invocation} is created, +such that: \begin{itemize} \item \code{$im$.isMethod} evaluates to \TRUE. \item \code{$im$.memberName} evaluates to the symbol \code{\#call}. @@ -12581,10 +12764,10 @@ \subsubsection{Function Expression Invocation} \commentary{% The situation where \code{noSuchMethod} is invoked can only arise -when the static type of $e_f$ is \DYNAMIC{}. +when the static type of $e_f$ is \DYNAMIC. The run-time semantics ensures that a function invocation may amount to an invocation of -the instance method \CALL{}. +the instance method \CALL. However, an interface type with a method named \CALL{} is not itself a subtype of any function type (\ref{subtypeRules}).% @@ -12707,7 +12890,7 @@ \subsubsection{Generic Function Instantiation} \LMHash{}% Let $f$ of the form -\syntax{ ('.'~\,('.'~)?)?}~be +\syntax{ (`.'~\,(`.'~)?)?}~be an expression that denotes a declaration of a local function, a static method, or a top-level function, and let $G$ be the static type of $f$. @@ -12808,7 +12991,7 @@ \subsubsection{Generic Function Instantiation} it is guaranteed that $o_1$ and $o_2$ are equal according to operator \lit{==}. However, it is unspecified whether -\code{identical($o_1$, $o_2$)} evaluates to \TRUE{} or \FALSE{}. +\code{identical($o_1$, $o_2$)} evaluates to \TRUE{} or \FALSE. \rationale{% No notion of equality is appropriate @@ -12882,7 +13065,7 @@ \subsection{Lookup} in different situations.% } -{ % Scope for 'lookup' definition. +{ % Scope for `lookup' definition. \def\LookupDefinitionWithStart#1{ \LMHash{}% @@ -12947,7 +13130,9 @@ \subsection{Top level Getter Invocation} \LMLabel{topLevelGetterInvocation} \LMHash{}% -Evaluation of a top-level getter invocation $i$ of the form $m$, where $m$ is an identifier, proceeds as follows: +Evaluation of a top-level getter invocation $i$ of the form $m$, +where $m$ is an identifier, +proceeds as follows: \LMHash{}% The getter function $m$ is invoked. @@ -13371,7 +13556,7 @@ \subsubsection{Ordinary Invocation} and the static type of $i$ is \DYNAMIC. \rationale{% This means that for invocations of an instance method named \CALL, -a receiver of type \FUNCTION{} is treated like a receiver of type \DYNAMIC{}. +a receiver of type \FUNCTION{} is treated like a receiver of type \DYNAMIC. The expectation is that any concrete subclass of \FUNCTION{} will implement \CALL, but there is no method signature @@ -13381,14 +13566,14 @@ \subsubsection{Ordinary Invocation} Note that any use of \CALL{} on a subclass of \FUNCTION{} that fails to implement \CALL{} will provoke a compile-time error, -as this exemption is limited to type \FUNCTION{}, +as this exemption is limited to type \FUNCTION, and does not apply to its subtypes.% } \end{itemize} \LMHash{}% If $T$ did not have an accessible member named $m$ -the static type of $i$ is \DYNAMIC{}, +the static type of $i$ is \DYNAMIC, and no further static checks are performed on $i$ (\commentary{% except that subexpressions of $i$ are subject to their own static analysis% @@ -13401,7 +13586,8 @@ \subsubsection{Ordinary Invocation} and if the method lookup succeeded then let $F$ be the static type of $d$. \LMHash{}% -Otherwise, let $d$ be the result of getter lookup for $m$ in $T$ with respect to $L$ +Otherwise, let $d$ be the result of getter lookup +for $m$ in $T$ with respect to $L$, and let $F$ be the return type of $d$. (\commentary{ Since \code{$T$.$m$} exists we cannot have a failure in both lookups.% @@ -13469,6 +13655,7 @@ \subsubsection{Ordinary Invocation} and let $v_g$ be the returned object. Then the value of $i$ is the value of +\noindent \code{$v_g$<$A_1, \ldots,\ A_r$>($a_1,\ \ldots,\ a_n,\ x_{n+1}$: $a_{n+1},\ \ldots,\ x_{n+k}$: $a_{n+k}$)}. \LMHash{}% @@ -13500,7 +13687,7 @@ \subsubsection{Ordinary Invocation} \commentary{% The situation where \code{noSuchMethod} is invoked can only arise -when the static type of $e$ is \DYNAMIC{}. +when the static type of $e$ is \DYNAMIC. Notice that the wording avoids re-evaluating the receiver $o$ and the arguments $a_i$.% } @@ -13621,16 +13808,19 @@ \subsubsection{Super Invocation} \LMHash{}% A super method invocation $i$ has the form -\code{\SUPER{}.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}. +\noindent +\code{\SUPER.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}. \commentary{% -Note that non-generic invocations arise as the special case where the number of type arguments is zero, +Note that non-generic invocations arise as +the special case where the number of type arguments is zero, in which case the type argument list is omitted, and similarly for formal type parameter lists (\ref{generics}).% } \LMHash{}% -It is a compile-time error if a super method invocation occurs in a top-level function or variable initializer, +It is a compile-time error if a super method invocation occurs +in a top-level function or variable initializer, in an instance variable initializer or initializer list, in class \code{Object}, in a factory constructor, @@ -13657,7 +13847,8 @@ \subsubsection{Super Invocation} \LMHash{}% Otherwise (\commentary{when one of the lookups succeeded}), -the static analysis of $i$ is performed as specified in Section~\ref{bindingActualsToFormals}, +the static analysis of $i$ is performed +as specified in Section~\ref{bindingActualsToFormals}, considering the function to have static type $F$, and the static type of $i$ is as specified there. @@ -13670,7 +13861,7 @@ \subsubsection{Super Invocation} \LMHash{}% Evaluation of $i$ proceeds as follows: -Let $o$ be the current binding of \THIS{}, +Let $o$ be the current binding of \THIS, let $C$ be the enclosing class for $i$, and let \SuperClass{} be the superclass (\ref{superclasses}) of $C$. Let the declaration $d$ be the result of looking up @@ -13711,7 +13902,7 @@ \subsubsection{Sending Messages} Messages are sent by invoking specific methods in the Dart libraries; there is no specific syntax for sending a message. \commentary{% -In other words, the methods supporting sending messages +In other words, the methods supporting sending messages embody primitives of Dart that are not accessible to ordinary code, much like the methods that spawn isolates.% } @@ -13860,9 +14051,9 @@ \subsubsection{Getter Access and Method Extraction} \begin{itemize} \item The declared return type of \code{$T$.\id}, - if $T$ has an accessible instance getter named \id{}. + if $T$ has an accessible instance getter named \id. \item The function type of the method signature \code{$T$.\id}, - if $T$ has an accessible instance method named \id{}. + if $T$ has an accessible instance method named \id. \item \FUNCTION{} if $T$ is \FUNCTION{} bounded and \id{} is \CALL. \item The type \DYNAMIC{} otherwise. \commentary{This only occurs when $T$ is \DYNAMIC{} bounded.} @@ -13911,7 +14102,8 @@ \subsubsection{Getter Access and Method Extraction} \LMHash{}% If the getter lookup has failed, -then a new instance $im$ of the predefined class \code{Invocation} is created, such that: +then a new instance $im$ of the predefined class \code{Invocation} is created, +such that: \begin{itemize} \item \code{$im$.isGetter} evaluates to \TRUE. \item \code{$im$.memberName} evaluates to the symbol \code{m}. @@ -13927,12 +14119,13 @@ \subsubsection{Getter Access and Method Extraction} \end{itemize} \LMHash{}% -Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with argument $im$, +Then the method \code{noSuchMethod()} is looked up +in $o$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$. \commentary{% The situation where \code{noSuchMethod} is invoked can only arise -when the static type of $e$ is \DYNAMIC{}.% +when the static type of $e$ is \DYNAMIC.% } @@ -13965,7 +14158,8 @@ \subsubsection{Super Getter Access and Method Closurization} } \LMHash{}% -Evaluation of a property extraction $i$ of the form $\SUPER.m$ proceeds as follows: +Evaluation of a property extraction $i$ of the form $\SUPER.m$ +proceeds as follows: \LMHash{}% Let $g$ be the method implementation currently executing, @@ -13982,7 +14176,7 @@ \subsubsection{Super Getter Access and Method Closurization} Otherwise, $i$ is a getter invocation. Let $f$ be the result of looking up getter \id{} in $S$ with respect to $L$. -The body of $f$ is executed with \THIS{} bound to the current value of \THIS{}. +The body of $f$ is executed with \THIS{} bound to the current value of \THIS. The value of $i$ is the result returned by the call to the getter function. \commentary{% @@ -14017,7 +14211,9 @@ \subsubsection{Ordinary Member Closurization} is defined to be equivalent (\commentary{except for equality, as noted below}) to: \begin{itemize} -%\item $(a) \{\RETURN{}$ $u$ $op$ $a;$\} if $f$ is named $op$ and $op$ is one of \code{<, >, <=, >=, ==, -, +, /, \gtilde/, *, \%, $|$, \^{}, \&, $<<$, $>>$} (this precludes closurization of unary -). +%\item $(a) \{\RETURN{}$ $u$ $op$ $a;$\} if $f$ is named $op$ +% and $op$ is one of \code{<, >, <=, >=, ==, -, +, /, \gtilde/, *, \%, $|$, +% \^{}, \&, $<<$, $>>$} (this precludes closurization of unary -). %\item $() \{\RETURN{}$ \gtilde{} $u;$\} if $f$ is named \gtilde. %\item $(a) \{\RETURN{}$ $u[a];$\} if $f$ is named \code{[]}. %\item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named \code{[]=}. @@ -14029,7 +14225,7 @@ \subsubsection{Ordinary Member Closurization} \end{normativeDartCode} where $f$ is an instance method named $m$ which has type parameter declarations -\TypeParametersStd{}, +\TypeParametersStd, required parameters \List{p}{1}{n}, and named parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k}, using \code{null} for parameters whose default value is not specified. @@ -14041,7 +14237,7 @@ \subsubsection{Ordinary Member Closurization} \end{normativeDartCode} where $f$ is an instance method named $m$ which has type parameter declarations -\TypeParametersStd{}, +\TypeParametersStd, required parameters \List{p}{1}{n}, and optional positional parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k}, @@ -14051,7 +14247,8 @@ \subsubsection{Ordinary Member Closurization} \LMHash{}% $B'_j, j \in 1 .. s$, are determined as follows: If $o$ is an instance of a non-generic class, $B'_j = B_j, j \in 1 .. s$. -Otherwise, let $X'_1, \ldots, X'_{s'}$ be the formal type parameters of the class of $o$, +Otherwise, let $X'_1, \ldots, X'_{s'}$ be +the formal type parameters of the class of $o$, and $t'_1, \ldots, t'_{s'}$ be the actual type arguments. Then $B'_j = [t'_1/X'_1, \ldots, t'_{s'}/X'_{s'}]B_j, j \in 1 .. s$. @@ -14089,25 +14286,29 @@ \subsubsection{Ordinary Member Closurization} \LMHash{}% If $T$ is a non-generic class then for $j \in 1 .. n+k$, $T_j$ is a type annotation that denotes the same type as that -which is denoted by the type annotation on the corresponding parameter declaration in $D$. -If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC{}. +which is denoted by the type annotation on +the corresponding parameter declaration in $D$. +If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC. \LMHash{}% Otherwise $T$ is a generic instantiation of a generic class $G$. Let $X''_1, \ldots, X''_{s''}$ be the formal type parameters of $G$, and $t''_1, \ldots, t''_{s''}$ be the actual type arguments of $o$ at $T$. -Then $T_j$ is a type annotation that denotes $[t''_1/X''_1, \ldots, t''_{s''}/X''_{s''}]S_j$, +Then $T_j$ is a type annotation that denotes +$[t''_1/X''_1, \ldots, t''_{s''}/X''_{s''}]S_j$, where $S_j$ is the type annotation of the corresponding parameter in $D$. -If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC{}. +If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC. \LMHash{}% There is one way in which the function object yielded by the instance method closurization differs from -the function object obtained by function closurization on the above mentioned function literal: +the function object obtained by function closurization on +the above mentioned function literal: Assume that $o_1$ and $o_2$ are objects, $m$ is an identifier, and $c_1$ and $c_2$ are function objects obtained by closurization of $m$ on $o_1$ respectively $o_2$. -Then \code{$c_1$ == $c_2$} evaluates to true if and only if $o_1$ and $o_2$ is the same object. +Then \code{$c_1$ == $c_2$} evaluates to true +if and only if $o_1$ and $o_2$ is the same object. \commentary{% % Spell out the consequences for `==` and for `identical`, for the receivers @@ -14117,7 +14318,8 @@ \subsubsection{Ordinary Member Closurization} and two closurizations of a method $m$ from non-identical objects are not equal. Assuming that $v_i$ is a fresh variable bound to an object, $i \in 1 .. 2$, -it also follows that \code{identical($v_1.m, v_2.m$)} must be false when $v_1$ and $v_2$ are not bound to the same object. +it also follows that \code{identical($v_1.m, v_2.m$)} must be false +when $v_1$ and $v_2$ are not bound to the same object. However, Dart implementations are not required to canonicalize function objects, which means that \code{identical($v_1.m, v_2.m$)} is not guaranteed to be true, even when it is known that $v_1$ and $v_2$ are bound to the same object.% @@ -14144,9 +14346,11 @@ \subsubsection{Super Closurization} } \LMHash{}% -Consider expressions in the body of a class $T$ which is a subclass of a given class $S$, +Consider expressions in the body of a class $T$ which is +a subclass of a given class $S$, where a method declaration that implements $f$ exists in $S$, -and there is no class $U$ which is a subclass of $S$ and a superclass of $T$ which implements $f$. +and there is no class $U$ which is +a subclass of $S$ and a superclass of $T$ which implements $f$. \commentary{% In short, consider a situation where @@ -14162,7 +14366,9 @@ \subsubsection{Super Closurization} \LMHash{}% \begin{itemize} -%\item $(a) \{\RETURN{}$ \SUPER{} $op$ $a;$\} if $f$ is named $op$ and $op$ is one of \code{<, >, <=, >=, ==, -, +, /, \gtilde/, *, \%, $|$, \^{}, \&, $<<$, $>>$}. +%\item $(a) \{\RETURN{}$ \SUPER{} $op$ $a;$\} if $f$ is named $op$ +% and $op$ is one of \code{<, >, <=, >=, ==, -, +, /, \gtilde/, *, \%, $|$, +% \^{}, \&, $<<$, $>>$}. %\item $() \{\RETURN{}$ \gtilde\SUPER;\} if $f$ is named \gtilde. %\item $(a) \{\RETURN{}$ $\SUPER[a];$\} if $f$ is named \code{[]}. %\item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named \code{[]=}. @@ -14174,7 +14380,7 @@ \subsubsection{Super Closurization} \end{normativeDartCode} where $f$ is an instance method named $m$ which has type parameter declarations -\TypeParametersStd{}, +\TypeParametersStd, required parameters \List{p}{1}{n}, and named parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k}. \item @@ -14185,7 +14391,7 @@ \subsubsection{Super Closurization} \end{normativeDartCode} where $f$ is an instance method named $m$ which has type parameter declarations -\TypeParametersStd{}, +\TypeParametersStd, required parameters \List{p}{1}{n}, and optional positional parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k}. @@ -14233,33 +14439,38 @@ \subsubsection{Super Closurization} \LMHash{}% If $S$ is a non-generic class then for $j \in 1 .. n+k$, $T_j$ is a type annotation that denotes the same type as that -which is denoted by the type annotation on the corresponding parameter declaration in $D$. -If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC{}. +which is denoted by the type annotation on +the corresponding parameter declaration in $D$. +If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC. \LMHash{}% Otherwise $S$ is a generic instantiation of a generic class $G$. Let $X''_1, \ldots, X''_{s''}$ be the formal type parameters of $G$, and $t''_1, \ldots, t''_{s''}$ be the actual type arguments of $o$ at $S$. -Then $T_j$ is a type annotation that denotes $[t''_1/X''_1, \ldots, t''_{s''}/X''_{s''}]S_j$, +Then $T_j$ is a type annotation that denotes +$[t''_1/X''_1, \ldots, t''_{s''}/X''_{s''}]S_j$, where $S_j$ is the type annotation of the corresponding parameter in $D$. -If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC{}. +If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC. \LMHash{}% There is one way in which the function object yielded by the super closurization differs from -the function object obtained by function closurization on the above mentioned function literal: -Assume that an occurrence of the expression \SUPER{}.$m$ in a given class -is evaluated on two occasions where \THIS{} is bound to $o_1$ respectively $o_2$, +the function object obtained by function closurization on +the above mentioned function literal: +Assume that an occurrence of the expression \SUPER.$m$ in a given class +is evaluated on two occasions where \THIS{} +is bound to $o_1$ respectively $o_2$, and the resulting function objects are $c_1$ respectively $c_2$: -\code{$c_1$ == $c_2$} is then true if and only if $o_1$ and $o_2$ is the same object. +\code{$c_1$ == $c_2$} is then true +if and only if $o_1$ and $o_2$ is the same object. \subsubsection{Generic Method Instantiation} \LMLabel{genericMethodInstantiation} -%% TODO(eernst): Like generic function instantiation, generic method instantiation -%% relies on type inference. See the comment in \ref{genericFunctionInstantiation} -%% for further details. +%% TODO(eernst): Like generic function instantiation, generic method +%% instantiation relies on type inference. See the comment in +%% \ref{genericFunctionInstantiation} for further details. \LMHash{}% Generic method instantiation is a mechanism that yields @@ -14410,7 +14621,7 @@ \subsubsection{Generic Method Instantiation} \LMHash{}% Consider the situation where generic function type instantiation succeeded. -Let \gmiName{} be a fresh name which is associated with \id{}, +Let \gmiName{} be a fresh name which is associated with \id, which is private if and only if \id{} is private. \commentary{% An implementation could use, say, \code{foo_*} when \id{} is \code{foo}, @@ -14440,7 +14651,7 @@ \subsubsection{Generic Method Instantiation} \LMHash{}% Assume that a class $C$ declares a generic instance method named \id, with a method signature corresponding to a generic function type $G$, -formal type parameters \TypeParametersStd{}, +formal type parameters \TypeParametersStd, and formal parameter declarations \metavar{parameters}. Let \metavar{arguments} denote the corresponding actual argument list, passing these parameters. @@ -14495,7 +14706,7 @@ \subsubsection{Generic Method Instantiation} according to operator \lit{==}. It is unspecified whether \code{identical($o_1$, $o_2$)} -evaluates to \TRUE{} or \FALSE{}. +evaluates to \TRUE{} or \FALSE. } % End of scope for \gmiName. @@ -14683,12 +14894,12 @@ \subsection{Assignment} \Case{\code{$e_1$.$v$ = $e_2$}} Consider an assignment $a$ of the form \code{$e_1$.$v$ = $e_2$}. Let $T$ be the static type of $e_1$. -If $T$ is \DYNAMIC{}, no further checks are performed. +If $T$ is \DYNAMIC, no further checks are performed. Otherwise, it is a compile-time error unless $T$ has an accessible instance setter named \code{$v$=}. It is a compile-time error unless the static type of $e_2$ may be assigned to the declared type of the formal parameter of said setter. -Whether or not $T$ is \DYNAMIC{}, +Whether or not $T$ is \DYNAMIC, the static type of $a$ is the static type of $e_2$. \LMHash{}% @@ -14696,15 +14907,18 @@ \subsection{Assignment} proceeds as follows: 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 \code{$v$=} is looked up (\ref{lookup}) in $o_1$ with respect to the current library. +Then, the setter \code{$v$=} is looked up (\ref{lookup}) +in $o_1$ with respect to the current library. % This error can occur due to implicit casts and dynamic calls. It is a dynamic type error if the dynamic type of $o_2$ is not a subtype of the actual parameter type of said setter (\ref{actualTypes}). -Otherwise, the body of the setter is executed with its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$. +Otherwise, the body of the setter is executed with +its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$. \LMHash{}% -If the setter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that: +If the setter lookup has failed, then a new instance $im$ of +the predefined class \code{Invocation} is created, such that: \begin{itemize} \item \code{$im$.isSetter} evaluates to \TRUE. \item \code{$im$.memberName} evaluates to the symbol \code{v=}. @@ -14721,22 +14935,25 @@ \subsection{Assignment} \end{itemize} \LMHash{}% -Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked with argument $im$. +Then the method \code{noSuchMethod()} is looked up in $o_1$ +and invoked with argument $im$. \commentary{% The situation where \code{noSuchMethod} is invoked can only arise -when the static type of $e_1$ is \DYNAMIC{}.% +when the static type of $e_1$ is \DYNAMIC.% } \LMHash{}% -The value of the assignment expression is $o_2$ irrespective of whether setter lookup has failed or succeeded. +The value of the assignment expression is $o_2$ +irrespective of whether setter lookup has failed or succeeded. \EndCase \LMHash{}% \Case{\code{\SUPER.$v$ = $e$}} Consider an assignment $a$ of the form \code{\SUPER.$v$ = $e$}. Let $S_{static}$ be the superclass of the immediately enclosing class. -It is a compile-time error if $S_{static}$ does not have a concrete accessible instance setter named \code{$v$=}. +It is a compile-time error if $S_{static}$ does not have +a concrete accessible instance setter named \code{$v$=}. Otherwise, it is a compile-time error if the static type of $e$ may not be assigned to the static type of the formal parameter of said setter. The static type of $a$ is the static type of $e$. @@ -14744,12 +14961,14 @@ \subsection{Assignment} \LMHash{}% Evaluation of an assignment of the form \code{\SUPER.$v$ = $e$} proceeds as follows: -Let $g$ be the currently executing method, and let $C$ be the class in which $g$ was looked up. +Let $g$ be the currently executing method, and let $C$ be +the class in which $g$ was looked up. Let $S_{dynamic}$ be the superclass of $C$. The expression $e$ is evaluated to an object $o$. -Then, the setter \code{$v$=} is looked up (\ref{lookup}) in $S_{dynamic}$ with respect to the current library. +Then, the setter \code{$v$=} is looked up (\ref{lookup}) +in $S_{dynamic}$ with respect to the current library. The body of \code{$v$=} is executed with its formal parameter bound to $o$ -and \THIS{} bound to the current value of \THIS{}. +and \THIS{} bound to the current value of \THIS. \commentary{% The setter lookup will not fail, because it is a compile-time error @@ -14771,7 +14990,7 @@ \subsection{Assignment} \Case{\code{$e_1$[$e_2$] = $e_3$}} Consider an assignment $a$ of the form \code{$e_1$[$e_2$] = $e_3$}. Let $T$ be the static type of $e_1$. -If $T$ is \DYNAMIC{}, no further checks are performed. +If $T$ is \DYNAMIC, no further checks are performed. Otherwise, it is a compile-time error unless $T$ has a method named \code{[]=}. Let $S_2$ be the static type of the @@ -14779,7 +14998,7 @@ \subsection{Assignment} and $S_3$ the static type of the second. It is a compile-time error unless the static type of $e_2$ respectively $e_3$ may be assigned to $S_2$ respectively $S_3$. -Whether or not $T$ is \DYNAMIC{}, +Whether or not $T$ is \DYNAMIC, the static type of $a$ is the static type of $e_3$. \LMHash{}% @@ -14791,7 +15010,8 @@ \subsection{Assignment} Call the method \code{[]=} on $o$ with $i$ as first argument and $v$ as second argument. Then $a$ evaluates to $v$. -% Should we add: It is a dynamic error if $e_1$ evaluates to a constant list or map? +% Should we add: It is a dynamic error if $e_1$ evaluates to +% a constant list or map? \EndCase \LMHash{}% @@ -14929,9 +15149,10 @@ \subsubsection{Compound Assignment} Exactly the same compile-time errors that would be caused by \code{$e_1$.$v$ ??= $e_2$} are also generated in the case of $a$. -% Note: We use the static type of \code{$e_1$?.$v$} rather than \code{$e_1$.$v$} even -% though the latter would be simpler. This is because the former will remain correct -% if NNBD is introduced, and because it reduces the amount of synthetic syntax. +% Note: We use the static type of \code{$e_1$?.$v$} rather than +% \code{$e_1$.$v$} even though the latter would be simpler. This is because +% the former will remain correct if NNBD is introduced, and because it reduces +% the amount of synthetic syntax. The static type of $a$ is the least upper bound of the static type of \code{$e_1$?.$v$} and the static type of $e_2$. @@ -14995,7 +15216,8 @@ \subsubsection{Compound Assignment} Let $x$ and $i$ be fresh variables where the static type of the former is the static type of $e_1$ and the static type of the latter is the static type of $e_2$. -Except for errors inside $e_1$ and $e_2$ and references to the names $x$ and $i$, +Except for errors inside $e_1$ and $e_2$ and references to +the names $x$ and $i$, exactly the same compile-time errors that would be caused by \code{$x$[$i$] = $x$[$i$] $op$ $e_3$} are also generated in the case of $a$. @@ -15042,7 +15264,8 @@ \subsection{Conditional} \LMLabel{conditional} \LMHash{}% -A \Index{conditional expression} evaluates one of two expressions based on a boolean condition. +A \Index{conditional expression} evaluates one of two expressions +based on a boolean condition. \begin{grammar} ::= @@ -15050,13 +15273,15 @@ \subsection{Conditional} \end{grammar} \LMHash{}% -Evaluation of a conditional expression $c$ of the form $e_1 ? e_2 : e_3$ proceeds as follows: +Evaluation of a conditional expression $c$ of the form $e_1 ? e_2 : e_3$ +proceeds as follows: \LMHash{}% First, $e_1$ is evaluated to an object $o_1$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o_1$ is not \code{bool}. -If $r$ is \TRUE, then the value of $c$ is the result of evaluating the expression $e_2$. +If $r$ is \TRUE, then the value of $c$ is +the result of evaluating the expression $e_2$. Otherwise the value of $c$ is the result of evaluating the expression $e_3$. \LMHash{}% @@ -15066,21 +15291,24 @@ \subsection{Conditional} \begin{itemize} \item $v$ is potentially mutated in $e_2$, \item $v$ is potentially mutated within a function other -than the one where $v$ is declared, or + than the one where $v$ is declared, or \item $v$ is accessed by a function defined in $e_2$ and -$v$ is potentially mutated anywhere in the scope of $v$. + $v$ is potentially mutated anywhere in the scope of $v$. \end{itemize} \LMHash{}% -It is a compile-time error if the static type of $e_1$ may not be assigned to \code{bool}. -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$. +It is a compile-time error if +the static type of $e_1$ may not be assigned to \code{bool}. +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$. \subsection{If-null Expressions} \LMLabel{ifNull} \LMHash{}% -An \Index{if-null expression} evaluates an expression and if the result is the null object (\ref{null}), evaluates another. +An \Index{if-null expression} evaluates an expression and +if the result is the null object (\ref{null}), evaluates another. \begin{grammar} ::= (`??' )* @@ -15097,14 +15325,16 @@ \subsection{If-null Expressions} and then $e$ evaluates to $r$. \LMHash{}% -The static type of $e$ is the least upper bound (\ref{leastUpperBounds}) of the static type of $e_1$ and the static type of $e_2$. +The static type of $e$ is the least upper bound (\ref{leastUpperBounds}) of +the static type of $e_1$ and the static type of $e_2$. \subsection{Logical Boolean Expressions} \LMLabel{logicalBooleanExpressions} \LMHash{}% -The logical boolean expressions combine boolean objects using the boolean conjunction and disjunction operators. +The logical boolean expressions combine boolean objects using +the boolean conjunction and disjunction operators. \begin{grammar} ::= \gnewline{} @@ -15114,23 +15344,29 @@ \subsection{Logical Boolean Expressions} \end{grammar} \LMHash{}% -A \Index{logical boolean expression} is either an equality expression (\ref{equality}), or an invocation of a logical boolean operator on an expression $e_1$ with argument $e_2$. +A \Index{logical boolean expression} is either an equality expression +(\ref{equality}), +or an invocation of a logical boolean operator on +an expression $e_1$ with argument $e_2$. \LMHash{}% Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes the evaluation of $e_1$ to an object $o_1$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o_1$ is not \code{bool}. -If $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, otherwise $e_2$ is evaluated to an object $o_2$. +If $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, +otherwise $e_2$ is evaluated to an object $o_2$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o_2$ is not \code{bool}. Otherwise the result of evaluating $b$ is $o_2$. \LMHash{}% -Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes the evaluation of $e_1$ producing an object $o_1$. +Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ +causes the evaluation of $e_1$ producing an object $o_1$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o_1$ is not \code{bool}. -If $o_1$ is \FALSE, the result of evaluating $b$ is \FALSE, otherwise $e_2$ is evaluated to an object $o_2$. +If $o_1$ is \FALSE, the result of evaluating $b$ is \FALSE, +otherwise $e_2$ is evaluated to an object $o_2$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o_2$ is not \code{bool}. Otherwise the result of evaluating $b$ is $o_2$. @@ -15140,8 +15376,10 @@ \subsection{Logical Boolean Expressions} shows that a local variable $v$ has type $T$ if both of the following conditions hold: \begin{itemize} -\item Either $e_1$ shows that $v$ has type $T$ or $e_2$ shows that $v$ has type $T$. -\item $v$ is not mutated in $e_2$ or within a function other than the one where $v$ is declared. +\item Either $e_1$ shows that $v$ has type $T$ + or $e_2$ shows that $v$ has type $T$. +\item $v$ is not mutated in $e_2$ or within a function + other than the one where $v$ is declared. \end{itemize} \LMHash{}% @@ -15161,13 +15399,15 @@ \subsection{Logical Boolean Expressions} \item $v$ is potentially mutated in $e_1$, \item $v$ is potentially mutated in $e_2$, \item $v$ is potentially mutated within a function other -than the one where $v$ is declared, or + than the one where $v$ is declared, or \item $v$ is accessed by a function defined in $e_2$ and -$v$ is potentially mutated anywhere in the scope of $v$. + $v$ is potentially mutated anywhere in the scope of $v$. \end{itemize} \LMHash{}% -It is a compile-time error if the static type of $e_1$ may not be assigned to \code{bool} or if the static type of $e_2$ may not be assigned to \code{bool}. +It is a compile-time error if +the static type of $e_1$ may not be assigned to \code{bool} +or if the static type of $e_2$ may not be assigned to \code{bool}. The static type of a logical boolean expression is \code{bool}. @@ -15187,25 +15427,38 @@ \subsection{Equality} \end{grammar} \LMHash{}% -An \Index{equality expression} is either a relational expression (\ref{relationalExpressions}), or an invocation of an equality operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. +An \Index{equality expression} is either a relational expression +(\ref{relationalExpressions}), +or an invocation of an equality operator on either \SUPER{} +or an expression $e_1$, with argument $e_2$. \LMHash{}% -Evaluation of an equality expression $ee$ of the form \code{$e_1$ == $e_2$} proceeds as follows: +Evaluation of an equality expression $ee$ of the form \code{$e_1$ == $e_2$} +proceeds as follows: \begin{itemize} \item The expression $e_1$ is evaluated to an object $o_1$. \item The expression $e_2$ is evaluated to an object $o_2$. -\item If either $o_1$ or $o_2$ is the null object (\ref{null}), then $ee$ evaluates to \TRUE{} if both $o_1$ and $o_2$ are the null object and to \FALSE{} otherwise. +\item If either $o_1$ or $o_2$ is the null object (\ref{null}), + then $ee$ evaluates to \TRUE{} if both $o_1$ and $o_2$ are the null object + and to \FALSE{} otherwise. Otherwise, -\item evaluation of $ee$ is equivalent to the method invocation \code{$o_1$.==($o_2$)}. +\item evaluation of $ee$ is equivalent to the method invocation + \code{$o_1$.==($o_2$)}. \end{itemize} \LMHash{}% -Evaluation of an equality expression $ee$ of the form \code{\SUPER{} == $e$} proceeds as follows: +Evaluation of an equality expression $ee$ of the form +\code{\SUPER{} == $e$} +proceeds as follows: \begin{itemize} \item The expression $e$ is evaluated to an object $o$. -\item If either \THIS{} or $o$ is the null object (\ref{null}), then $ee$ evaluates to evaluates to \TRUE{} if both \THIS{} and $o$ are the null object and to \FALSE{} otherwise. +\item If either \THIS{} or $o$ is the null object (\ref{null}), + then $ee$ evaluates to evaluates to \TRUE{} + if both \THIS{} and $o$ are the null object + and to \FALSE{} otherwise. Otherwise, -\item evaluation of $ee$ is equivalent to the method invocation \code{\SUPER{}.==($o$)}. +\item evaluation of $ee$ is equivalent to the method invocation + \code{\SUPER.==($o$)}. \end{itemize} \commentary{% @@ -15213,19 +15466,24 @@ \subsection{Equality} user defined \lit{==} methods can assume that their argument is non-null, and avoid the standard boiler-plate prelude: -\code{if (identical(\NULL{}, arg)) return \FALSE{};} +\code{if (identical(\NULL, arg)) return \FALSE;} Another implication is that there is never a need -to use \code{identical()} to test against \NULL{}, +to use \code{identical()} to test against \NULL, nor should anyone ever worry about whether to write -\NULL{} == $e$ or $e$ == \NULL{}.% +\NULL{} == $e$ or $e$ == \NULL.% } \LMHash{}% -An equality expression of the form \code{$e_1$ != $e_2$} is equivalent to the expression \code{!($e_1$ == $e_2$)}. -An equality expression of the form \code{\SUPER{} != $e$} is equivalent to the expression \code{!(\SUPER{} == $e$)}. +An equality expression of the form \code{$e_1$ != $e_2$} is equivalent to +the expression \code{!($e_1$ == $e_2$)}. +An equality expression of the form \code{\SUPER{} != $e$} is equivalent to +the expression \code{!(\SUPER{} == $e$)}. -%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{}. +%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. \LMHash{}% The static type of an equality expression is \code{bool}. @@ -15249,11 +15507,16 @@ \subsection{Relational Expressions} \end{grammar} \LMHash{}% -A \Index{relational expression} is either a bitwise expression (\ref{bitwiseExpressions}), or an invocation of a relational operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. +A \Index{relational expression} is either a bitwise expression +(\ref{bitwiseExpressions}), +or an invocation of a relational operator on either \SUPER{} +or an expression $e_1$, with argument $e_2$. \LMHash{}% -A relational expression of the form $e_1$ $op$ $e_2$ is equivalent to the method invocation \code{$e_1$.$op$($e_2$)}. -A relational expression of the form \SUPER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)}. +A relational expression of the form $e_1$ $op$ $e_2$ is equivalent to +the method invocation \code{$e_1$.$op$($e_2$)}. +A relational expression of the form \SUPER{} $op$ $e_2$ is equivalent to +the method invocation \code{\SUPER.$op$($e_2$)}. \subsection{Bitwise Expressions} @@ -15280,11 +15543,16 @@ \subsection{Bitwise Expressions} \end{grammar} \LMHash{}% -A \Index{bitwise expression} is either a shift expression (\ref{shift}), or an invocation of a bitwise operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. +A \Index{bitwise expression} is either a shift expression (\ref{shift}), +or an invocation of a bitwise operator +on either \SUPER{} or an expression $e_1$, +with argument $e_2$. \LMHash{}% -A bitwise expression of the form \code{$e_1$ $op$ $e_2$} is equivalent to the method invocation $e_1.op(e_2)$. -A bitwise expression of the form \code{\SUPER{} $op$ $e_2$} is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)}. +A bitwise expression of the form \code{$e_1$ $op$ $e_2$} is equivalent to +the method invocation $e_1.op(e_2)$. +A bitwise expression of the form \code{\SUPER{} $op$ $e_2$} is equivalent to +the method invocation \code{\SUPER.$op$($e_2$)}. \commentary{% It should be obvious that the static type rules for these expressions @@ -15312,11 +15580,17 @@ \subsection{Shift} \end{grammar} \LMHash{}% -A \Index{shift expression} is either an additive expression (\ref{additiveExpressions}), or an invocation of a shift operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. +A \Index{shift expression} is either an additive expression +(\ref{additiveExpressions}), +or an invocation of a shift operator +on either \SUPER{} or an expression $e_1$, +with argument $e_2$. \LMHash{}% -A shift expression of the form $e_1$ $op$ $e_2$ is equivalent to the method invocation \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$)}. +A shift expression of the form $e_1$ $op$ $e_2$ is equivalent to +the method invocation \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$)}. \commentary{% Note that this definition implies left-to-right evaluation order @@ -15345,17 +15619,31 @@ \subsection{Additive Expressions} \end{grammar} \LMHash{}% -An \Index{additive expression} is either a multiplicative expression (\ref{multiplicativeExpressions}), or an invocation of an additive operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. +An \Index{additive expression} is either a multiplicative expression +(\ref{multiplicativeExpressions}), +or an invocation of an additive operator +on either \SUPER{} or an expression $e_1$, +with argument $e_2$. \LMHash{}% -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$)}. +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$)}. \LMHash{}% -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 operators \code{+} and \code{-} of class \code{int} are treated specially by the typechecker. -The static type of an expression $e_1 + e_2$ where $e_1$ has static type \code{int} is \code{int} if the static type of $e_2$ is \code{int}, and \code{double} if the static type of $e_2$ is \code{double}. -The static type of an expression $e_1 - e_2$ where $e_1$ has static type \code{int} is \code{int} if the static type of $e_2$ is \code{int}, and \code{double} if the static type of $e_2$ is \code{double}. +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 operators \code{+} and \code{-} of class \code{int} +are treated specially by the typechecker. +The static type of an expression $e_1 + e_2$ +where $e_1$ has static type \code{int} +is \code{int} if the static type of $e_2$ is \code{int}, +and \code{double} if the static type of $e_2$ is \code{double}. +The static type of an expression $e_1 - e_2$ +where $e_1$ has static type \code{int} +is \code{int} if the static type of $e_2$ is \code{int}, +and \code{double} if the static type of $e_2$ is \code{double}. \subsection{Multiplicative Expressions} @@ -15376,17 +15664,31 @@ \subsection{Multiplicative Expressions} \end{grammar} \LMHash{}% - A \Index{multiplicative expression} is either a unary expression (\ref{unaryExpressions}), or an invocation of a multiplicative operator on either \SUPER{} or an expression $e_1$, with argument $e_2$. +A \Index{multiplicative expression} is either a unary expression +(\ref{unaryExpressions}), +or an invocation of a multiplicative operator +on either \SUPER{} or an expression $e_1$, +with argument $e_2$. \LMHash{}% -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 form \SUPER{} $op$ $e_2$ is equivalent to the method invocation \code{\SUPER{}.$op$($e_2$)}. +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 form \SUPER{} $op$ $e_2$ is equivalent to +the method invocation \code{\SUPER.$op$($e_2$)}. \LMHash{}% -The static type of an multiplicative expression is usually determined by the signature given in the declaration of the operator used. -However, invocations of the operators \code{*} and \code{\%} of class \code{int} are treated specially by the typechecker. -The static type of an expression $e_1 * e_2$ where $e_1$ has static type \code{int} is \code{int} if the static type of $e_2$ is \code{int}, and \code{double} if the static type of $e_2$ is \code{double}. -The static type of an expression $e_1 \% e_2$ where $e_1$ has static type \code{int} is \code{int} if the static type of $e_2$ is \code{int}, and \code{double} if the static type of $e_2$ is \code{double}. +The static type of an multiplicative expression is usually determined by +the signature given in the declaration of the operator used. +However, invocations of the operators \code{*} and \code{\%} of class \code{int} +are treated specially by the typechecker. +The static type of an expression $e_1 * e_2$ +where $e_1$ has static type \code{int} +is \code{int} if the static type of $e_2$ is \code{int}, +and \code{double} if the static type of $e_2$ is \code{double}. +The static type of an expression $e_1 \% e_2$ +where $e_1$ has static type \code{int} +is \code{int} if the static type of $e_2$ is \code{int}, +and \code{double} if the static type of $e_2$ is \code{double}. \subsection{Unary Expressions} @@ -15414,7 +15716,11 @@ \subsection{Unary Expressions} \end{grammar} \LMHash{}% -A \Index{unary expression} is either a postfix expression (\ref{postfixExpressions}), an await expression (\ref{awaitExpressions}) or an invocation of a prefix operator on an expression or an invocation of a unary operator on either \SUPER{} or an expression $e$. +A \Index{unary expression} is either a postfix expression +(\ref{postfixExpressions}), +an await expression (\ref{awaitExpressions}) +or an invocation of a prefix operator on an expression +or an invocation of a unary operator on either \SUPER{} or an expression $e$. \LMHash{}% The expression $!e$ is treated as @@ -15460,15 +15766,18 @@ \subsection{Unary Expressions} \LMHash{}% Any other 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 to -the method invocation (\ref{superInvocation}) \code{\SUPER{}.$op()$}. +An expression of the form \code{$op$ \SUPER} is equivalent to +the method invocation (\ref{superInvocation}) \code{\SUPER.$op()$}. \subsection{Await Expressions} \LMLabel{awaitExpressions} \LMHash{}% -An \Index{await expression} allows code to yield control until an asynchronous operation (\ref{functions}) completes. +An \Index{await expression} allows code to +yield control until an asynchronous operation +(\ref{functions}) +completes. \begin{grammar} ::= \AWAIT{} @@ -15488,18 +15797,26 @@ \subsection{Await Expressions} % NOTICE: Removed the requirement that an error thrown by $e$ is caught in a % future. There is no reason $var x = e; await x;$ and $await e$ should behave % differently, and no implementation actually implemented it. -If the run-time type of $o$ is a subtype of \code{Future<$T$>}, then let $f$ be $o$; otherwise let $f$ be the result of creating a new object using the constructor \code{Future<$T$>.value()} with $o$ as its argument. +If the run-time type of $o$ is a subtype of \code{Future<$T$>}, +then let $f$ be $o$; +otherwise let $f$ be the result of creating +a new object using the constructor \code{Future<$T$>.value()} +with $o$ as its argument. \LMHash{}% -Next, the stream associated with the innermost enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused. -The current invocation of the function body immediately enclosing $a$ is suspended until after $f$ completes. +Next, the stream associated with the innermost enclosing asynchronous for loop +(\ref{asynchronousFor-in}), +if any, is paused. +The current invocation of the function body immediately enclosing $a$ +is suspended until after $f$ completes. At some time after $f$ is completed, control returns to the current invocation. If $f$ has completed with an error $x$ and stack trace $t$, $a$ throws $x$ and $t$ (\ref{expressionEvaluation}). If $f$ completes with an object $v$, $a$ evaluates to $v$. -%Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$. +% Otherwise, the value of $a$ is the value of $e$. If evaluation of +% $e$ raises an exception $x$, $a$ raises $x$. \commentary{% An await expression can only occur in a function which is declared @@ -15692,7 +16009,7 @@ \subsection{Postfix Expressions} or if the return type of this operator is not assignable to the second argument type of said operator \lit{[]=}. % We allow `e1[e2]++;` also when the entry has static type double, -% so we can't just say 'assignable'. +% so we can't just say `assignable'. A compile-time error occurs if passing the integer literal \code{1} as an argument to said operator \lit{+} or \lit{-} would be an error. The static type of $e$ is $T$. @@ -15713,7 +16030,8 @@ \subsection{Postfix Expressions} \Case{\code{$e_1$?.$v$++}, \code{$e_1$?.$v$-{}-}} Consider a postfix expression $e$ of the form \code{$e_1$?.$v$\,\op} where \op{} is either \lit{++} or \lit{-{}-}. -Exactly the same compile-time errors that would be caused by \code{$e_1$.$v$\,\op} +Exactly the same compile-time errors that would be caused by +\code{$e_1$.$v$\,\op} are also generated in the case of \code{$e_1$?.$v$\,\op}. The static type of $e$ is the static type of \code{$e_1$.$v$}. @@ -15735,8 +16053,10 @@ \subsection{Assignable Expressions} \LMLabel{assignableExpressions} \LMHash{}% -Assignable expressions are expressions that can appear on the left hand side of an assignment. -This section describes how to evaluate these expressions when they do not constitute the complete left hand side of an assignment. +Assignable expressions are expressions +that can appear on the left hand side of an assignment. +This section describes how to evaluate these expressions +when they do not constitute the complete left hand side of an assignment. \rationale{% Of course, if assignable expressions @@ -15767,26 +16087,35 @@ \subsection{Assignable Expressions} An \Index{assignable expression} is either: \begin{itemize} \item An identifier. -\item An invocation (possibly conditional) of a getter (\ref{getters}) or list access operator on an expression $e$. -\item An invocation of a getter or list access operator on \SUPER{}. +\item An invocation (possibly conditional) of a getter (\ref{getters}) + or list access operator on an expression $e$. +\item An invocation of a getter or list access operator on \SUPER. \end{itemize} \LMHash{}% -An assignable expression of the form \id{} is evaluated as an identifier expression (\ref{identifierReference}). +An assignable expression of the form \id{} is evaluated as +an identifier expression (\ref{identifierReference}). -%An assignable expression of the form \code{$e$.\id($a_1, \ldots,\ a_n$)} is evaluated as a method invocation (\ref{methodInvocation}). +%An assignable expression of the form \code{$e$.\id($a_1, \ldots,\ a_n$)} +% is evaluated as a method invocation (\ref{methodInvocation}). \LMHash{}% -An assignable expression of the form \code{$e$.\id} or \code{$e$?.\id} is evaluated as a property extraction (\ref{propertyExtraction}). +An assignable expression of the form \code{$e$.\id} or \code{$e$?.\id} +is evaluated as a property extraction (\ref{propertyExtraction}). \LMHash{}% -An assignable expression of the form \code{$e_1$[$e_2$]} is evaluated as a method invocation of the operator method \code{[]} on $e_1$ with argument $e_2$. +An assignable expression of the form \code{$e_1$[$e_2$]} +is evaluated as a method invocation of +the operator method \code{[]} on $e_1$ with argument $e_2$. \LMHash{}% -An assignable expression of the form \code{\SUPER{}.\id} is evaluated as a property extraction. +An assignable expression of the form \code{\SUPER.\id} is evaluated as +a property extraction. \LMHash{}% -Evaluation of an assignable expression of the form \code{\SUPER{}[$e_2$]} is equivalent to evaluation of the method invocation \code{\SUPER{}.[]($e_2$)}. +Evaluation of an assignable expression of the form \code{\SUPER{}[$e_2$]} +is equivalent to +evaluation of the method invocation \code{\SUPER.[]($e_2$)}. \subsection{Lexical Lookup} @@ -16023,7 +16352,8 @@ \subsection{Identifier Reference} \LMLabel{identifierReference} \LMHash{}% -An \Index{identifier expression} consists of a single identifier; it provides access to an object via an unqualified name. +An \Index{identifier expression} consists of a single identifier; +it provides access to an object via an unqualified name. \begin{grammar} ::= @@ -16098,7 +16428,7 @@ \subsection{Identifier Reference} \LMHash{}% It is a compile-time error if either of the identifiers \AWAIT{} or \YIELD{} is used as an identifier in a function body -marked with either \ASYNC{}, \code{\ASYNC*} or \code{\SYNC*}. +marked with either \ASYNC, \code{\ASYNC*} or \code{\SYNC*}. \rationale{% This makes the identifiers \AWAIT{} and \YIELD{} behave like reserved words @@ -16235,7 +16565,7 @@ \subsection{Identifier Reference} If $D$ is a type parameter $X$ then the value of $e$ is the value of the actual type argument corresponding to $X$ that was passed to the generative constructor that created - the current binding of \THIS{}. + the current binding of \THIS. \item If $D$ is the declaration of a library getter (\commentary{which may be implicitly induced by a library variable}), @@ -16258,7 +16588,7 @@ \subsection{Identifier Reference} \item If $D$ is an instance getter declaration in an extension declaration $E$, then $e$ evaluates to the result of invoking said getter - with the current binding of \THIS{}, and + with the current binding of \THIS, and the current bindings of the type parameters declared by $D$. \item If $D$ is an instance method declaration in an extension declaration $E$ @@ -16330,9 +16660,9 @@ \subsection{Type Test} This makes sense in a language where everything is an object. Also note that \code{\NULL{} \IS{} $T$} is false -unless $T = \code{Object}$, $T = \code{\DYNAMIC{}}$ or $T = \code{Null}$. +unless $T = \code{Object}$, $T = \code{\DYNAMIC}$ or $T = \code{Null}$. The former two are useless, as is anything -of the form \code{$e$ \IS{} Object} or \code{$e$ \IS{} \DYNAMIC{}}. +of the form \code{$e$ \IS{} Object} or \code{$e$ \IS{} \DYNAMIC}. Users should test for the null object (\ref{null}) directly rather than via type tests.% } @@ -16582,8 +16912,10 @@ \subsection{Local Variable Declaration} if $v$ is mutable, and an assignment to $v$ occurs in $s$. \LMHash{}% -A local variable declaration of the form \code{\VAR{} $v$;} is equivalent to \code{\VAR{} $v$ = \NULL{};}. -A local variable declaration of the form \code{$T$ $v$;} is equivalent to \code{$T$ $v$ = \NULL{};}. +A local variable declaration of the form \code{\VAR{} $v$;} is equivalent to +\code{\VAR{} $v$ = \NULL;}. +A local variable declaration of the form \code{$T$ $v$;} is equivalent to +\code{$T$ $v$ = \NULL;}. \commentary{% This holds regardless of the type $T$. @@ -16600,12 +16932,13 @@ \subsection{Local Variable Declaration} \code{\VAR{} $v$ = $e$;} \code{\CONST{} $v$ = $e$;} \code{\FINAL{} $v$ = $e$;} -is \DYNAMIC{}. +is \DYNAMIC. \LMHash{}% Let $v$ be a local variable declared by an initializing variable declaration, and let $e$ be the associated initializing expression. -It is a compile-time error if the static type of $e$ is not assignable to the type of $v$. +It is a compile-time error if the static type of $e$ is not assignable to +the type of $v$. It is a compile-time error if a local variable $v$ is final, and the declaration of $v$ is not an initializing variable declaration. @@ -16718,7 +17051,8 @@ \subsection{Local Function Declaration} \LMLabel{localFunctionDeclaration} \LMHash{}% -A function declaration statement declares a new local function (\ref{functionDeclarations}). +A function declaration statement declares a new local function +(\ref{functionDeclarations}). \begin{grammar} ::= @@ -16795,8 +17129,14 @@ \subsection{If} \end{grammar} \LMHash{}% -An if statement of the form \code{\IF{} ($e$) $s_1$ \ELSE{} $s_2$} where $s_1$ is not a block statement is equivalent to the statement \code{\IF{} ($e$) \{$s_1$\} \ELSE{} $s_2$}. -An if statement of the form \code{\IF{} ($e$) $s_1$ \ELSE{} $s_2$} where $s_2$ is not a block statement is equivalent to the statement \code{\IF{} ($e$) $s_1$ \ELSE{} \{$s_2$\}}. +An if statement of the form +\code{\IF{} ($e$) $s_1$ \ELSE{} $s_2$} +where $s_1$ is not a block statement is equivalent to the statement +\code{\IF{} ($e$) \{$s_1$\} \ELSE{} $s_2$}. +An if statement of the form +\code{\IF{} ($e$) $s_1$ \ELSE{} $s_2$} +where $s_2$ is not a block statement is equivalent to the statement +\code{\IF{} ($e$) $s_1$ \ELSE{} \{$s_2$\}}. \rationale{% The reason for this equivalence is to catch errors such as% @@ -16812,13 +17152,13 @@ \subsection{If} \rationale{% 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{somePredicate} is false, +If we assume that \code{v} is declared +in the scope of the method \code{main()}, +then when \code{somePredicate} is false, \code{v} will be uninitialized when accessed. -The cleanest approach would be to require a block following the test, +The cleanest approach would be to require a block following the test, rather than an arbitrary statement. -However, this goes against long standing custom, +However, this goes against long standing custom, undermining Dart's goal of familiarity. Instead, we choose to insert a block, introducing a scope, around the statement following the predicate @@ -16831,16 +17171,21 @@ \subsection{If} } \LMHash{}% -Execution of an if statement of the form \code{\IF{} ($b$) $s_1$ \ELSE{} $s_2$} where $s_1$ and $s_2$ are block statements, proceeds as follows: +Execution of an if statement of the form +\code{\IF{} ($b$) $s_1$ \ELSE{} $s_2$} +where $s_1$ and $s_2$ are block statements, +proceeds as follows: \LMHash{}% First, the expression $b$ is evaluated to an object $o$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o$ is not \code{bool}. -If $o$ is \TRUE{}, then the block statement $s_1$ is executed, otherwise the block statement $s_2$ is executed. +If $o$ is \TRUE, then the block statement $s_1$ is executed, +otherwise the block statement $s_2$ is executed. \LMHash{}% -It is a compile-time error if the type of the expression $b$ may not be assigned to \code{bool}. +It is a compile-time error if the type of the expression $b$ +may not be assigned to \code{bool}. \LMHash{}% If $b$ shows that a local variable $v$ has type $T$, @@ -16849,13 +17194,14 @@ \subsection{If} \begin{itemize} \item $v$ is potentially mutated in $s_1$, \item $v$ is potentially mutated within a function other -than the one where $v$ is declared, or + than the one where $v$ is declared, or \item $v$ is accessed by a function defined in $s_1$ and -$v$ is potentially mutated anywhere in the scope of $v$. + $v$ is potentially mutated anywhere in the scope of $v$. \end{itemize} \LMHash{}% -An if statement of the form \code{\IF{} ($e$) $s$} is equivalent to the if statement \code{\IF{} ($e$) $s$ \ELSE{} \{\}}. +An if statement of the form \code{\IF{} ($e$) $s$} is equivalent to +the if statement \code{\IF{} ($e$) $s$ \ELSE{} \{\}}. \subsection{For} @@ -16876,7 +17222,8 @@ \subsection{For} \end{grammar} \LMHash{}% - The for statement has three forms - the traditional for loop and two forms of the for-in statement - synchronous and asynchronous. +The for statement has three forms - the traditional for loop +and two forms of the for-in statement - synchronous and asynchronous. \subsubsection{For Loop} @@ -16894,28 +17241,31 @@ \subsubsection{For Loop} Then: \begin{enumerate} \item -\label{beginFor} -If this is the first iteration of the for loop, let $v'$ be $v$. -Otherwise, let $v'$ be the variable $v''$ created in the previous execution of step \ref{allocateFreshVar}. + \label{beginFor} + If this is the first iteration of the for loop, let $v'$ be $v$. + Otherwise, let $v'$ be the variable $v''$ created in + the previous execution of step \ref{allocateFreshVar}. \item -The expression $[v'/v]c$ is evaluated to an object $o$. -% This error can occur due to implicit casts and null. -It is a dynamic error if the run-time type of $o$ is not \code{bool}. -If $o$ is \FALSE{}, the for loop completes normally. -Otherwise, execution continues at step \ref{beginIteration}. + The expression $[v'/v]c$ is evaluated to an object $o$. + % This error can occur due to implicit casts and null. + It is a dynamic error if the run-time type of $o$ is not \code{bool}. + If $o$ is \FALSE, the for loop completes normally. + Otherwise, execution continues at step \ref{beginIteration}. \item -\label{beginIteration} -The statement $[v'/v]\{s\}$ is executed. + \label{beginIteration} + The statement $[v'/v]\{s\}$ is executed. -If this execution completes normally, continues without a label, -or continues to a label (\ref{labels}) that prefixes this \FOR{} statement (\ref{statementCompletion}), -then execution of the statement is treated as if it had completed normally. + If this execution completes normally, continues without a label, + or continues to a label (\ref{labels}) + that prefixes this \FOR{} statement (\ref{statementCompletion}), + then execution of the statement is treated as if it had completed normally. -\label{allocateFreshVar} -Let $v''$ be a fresh variable. -$v''$ is bound to the value of $v'$. + \label{allocateFreshVar} + Let $v''$ be a fresh variable. + $v''$ is bound to the value of $v'$. \item -The expression $[v''/v]e$ is evaluated, and the process recurses at step \ref{beginFor}. + The expression $[v''/v]e$ is evaluated, and + the process recurses at step \ref{beginFor}. \end{enumerate} \rationale{% @@ -16935,9 +17285,11 @@ \subsubsection{For Loop} } \LMHash{}% -It is a compile-time error if the static type of $c$ may not be assigned to \code{bool}. +It is a compile-time error if the static type of $c$ +may not be assigned to \code{bool}. -%A for statement of the form \code{\FOR{} ($d$ ; $c$; $e$) $s$} is equivalent to the following code: +%A for statement of the form \code{\FOR{} ($d$ ; $c$; $e$) $s$} +%is equivalent to the following code: %\code{ %\{$d$; @@ -16947,7 +17299,7 @@ \subsubsection{For Loop} %\}\} %} -%If $c$ is empty, it is interpreted as \TRUE{}. +%If $c$ is empty, it is interpreted as \TRUE. \subsubsection{For-in} @@ -16973,7 +17325,8 @@ \subsubsection{For-in} (\ref{superBoundedTypes}) then $T$ is \code{Iterable<\DYNAMIC>}, otherwise $T$ is the static type of $e$. -It is a compile-time error if $T$ is not assignable to \code{Iterable<\DYNAMIC>}. +It is a compile-time error if $T$ is not assignable to +\code{Iterable<\DYNAMIC>}. \commentary{% It follows that it is a compile-time error @@ -16990,7 +17343,8 @@ \subsubsection{Asynchronous For-in} \LMHash{}% A for-in statement may be asynchronous. The asynchronous form is designed to iterate over streams. -An asynchronous for loop is distinguished by the keyword \AWAIT{} immediately preceding the keyword \FOR. +An asynchronous for loop is distinguished by +the keyword \AWAIT{} immediately preceding the keyword \FOR. \LMHash{}% Let $D$ be derived from \syntax{?}. @@ -17001,11 +17355,13 @@ \subsubsection{Asynchronous For-in} \LMHash{}% The expression $e$ is evaluated to an object $o$. % This error can occur due to implicit casts and null. -It is a dynamic type error if $o$ is not an instance of a class that implements \code{Stream}. +It is a dynamic type error if $o$ is not an instance of +a class that implements \code{Stream}. It is a compile-time error if $D$ is empty and \id{} is a final variable. \LMHash{}% -The stream associated with the innermost enclosing asynchronous for loop, if any, is paused. +The stream associated with the innermost enclosing asynchronous for loop, +if any, is paused. The stream $o$ is listened to, producing a stream subscription $u$, and execution of the asynchronous for-in loop is suspended until a stream event is available. @@ -17014,9 +17370,11 @@ \subsubsection{Asynchronous For-in} while this loop is waiting for stream events.% } -Pausing an asynchronous for loop means pausing the associated stream subscription. +Pausing an asynchronous for loop means pausing +the associated stream subscription. A stream subscription is paused by calling its \code{pause} method. -If the subscription is already paused, an implementation may omit further calls to \code{pause}. +If the subscription is already paused, an implementation may omit +further calls to \code{pause}. \commentary{% The \code{pause} call can throw, although that should never happen @@ -17025,11 +17383,12 @@ \subsubsection{Asynchronous For-in} \LMHash{}% For each \Index{data event} from $u$, -the statement $s$ is executed with \id{} bound to the value of the current data event. +the statement $s$ is executed with \id{} bound to +the value of the current data event. \commentary{% Either execution of $s$ is completely synchronous, or it contains an -asynchronous construct (\AWAIT{}, \AWAIT{} \FOR{}, \YIELD{} or \YIELD*) +asynchronous construct (\AWAIT, \code{\AWAIT\,\,\FOR}, \YIELD, or \YIELD*) which will pause the stream subscription of its surrounding asynchronous loop. This ensures that no other event of $u$ occurs before execution of $s$ is complete, @@ -17040,16 +17399,24 @@ \subsubsection{Asynchronous For-in} } \LMHash{}% -If execution of $s$ continues without a label, or to a label (\ref{labels}) that prefixes the asynchronous for statement (\ref{statementCompletion}), then the execution of $s$ is treated as if it had completed normally. +If execution of $s$ continues without a label, +or to a label (\ref{labels}) +that prefixes the asynchronous for statement (\ref{statementCompletion}), +then the execution of $s$ is treated as if it had completed normally. -If execution of $s$ otherwise does not complete normally, the subscription $u$ is canceled by evaluating \code{\AWAIT{} $v$.cancel()} where $v$ is a fresh variable referencing the stream subscription $u$. +\LMHash{}% +If execution of $s$ otherwise does not complete normally, +the subscription $u$ is canceled by evaluating \code{\AWAIT{} $v$.cancel()} +where $v$ is a fresh variable referencing the stream subscription $u$. If that evaluation throws, execution of $f$ throws the same exception and stack trace. Otherwise execution of $f$ completes in the same way as the execution of $s$. % Notice: The previous specification was unclear about what happened when % a subscripton is canceled. This text is explicit, and existing % implementations may not properly await the cancel call. -Otherwise the execution of $f$ is suspended again, waiting for the next stream subscription event, and $u$ is resumed if it has been paused. +Otherwise the execution of $f$ is suspended again, waiting for +the next stream subscription event, +and $u$ is resumed if it has been paused. \commentary{% The \code{resume} call can throw, in which case the asynchronous for loop also throws. @@ -17063,17 +17430,20 @@ \subsubsection{Asynchronous For-in} where $v$ is a fresh variable referencing the stream subscription $u$. If that evaluation throws, execution of $f$ throws the same exception object and stack trace. -Otherwise execution of $f$ throws with $e$ as exception object and $st$ as stack trace. +Otherwise execution of $f$ throws +with $e$ as exception object and $st$ as stack trace. \LMHash{}% When $u$ is done, execution of $f$ completes normally. \LMHash{}% -It is a compile-time error if an asynchronous for-in statement appears inside a synchronous function (\ref{functions}). -It is a compile-time error if a traditional for loop (\ref{forLoop}) is prefixed by the \AWAIT{} keyword. +It is a compile-time error if an asynchronous for-in statement appears +inside a synchronous function (\ref{functions}). +It is a compile-time error if a traditional for loop (\ref{forLoop}) is +prefixed by the \AWAIT{} keyword. \rationale{% -An asynchronous loop would make no sense within a synchronous function, +An asynchronous loop would make no sense within a synchronous function, for the same reasons that an await expression makes no sense in a synchronous function.% } @@ -17083,14 +17453,16 @@ \subsection{While} \LMLabel{while} \LMHash{}% -The while statement supports conditional iteration, where the condition is evaluated prior to the loop. +The while statement supports conditional iteration, +where the condition is evaluated prior to the loop. \begin{grammar} ::= \WHILE{} `(' `)' \end{grammar} \LMHash{}% -Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} proceeds as follows: +Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;} +proceeds as follows: \LMHash{}% The expression $e$ is evaluated to an object $o$. @@ -17098,12 +17470,17 @@ \subsection{While} It is a dynamic error if the run-time type of $o$ is not \code{bool}. \LMHash{}% -If $o$ is \FALSE{}, then execution of the while statement completes normally (\ref{statementCompletion}). +If $o$ is \FALSE, then execution of the while statement completes normally +(\ref{statementCompletion}). \LMHash{}% Otherwise $o$ is \TRUE{} and then the statement $\{s\}$ is executed. -If that execution completes normally or it continues with no label or to a label (\ref{labels}) that prefixes the \WHILE{} statement (\ref{statementCompletion}), then the while statement is re-executed. -If the execution breaks without a label, execution of the while statement completes normally. +If that execution completes normally or it continues with no label +or to a label (\ref{labels}) that prefixes the \WHILE{} statement +(\ref{statementCompletion}), +then the while statement is re-executed. +If the execution breaks without a label, +execution of the while statement completes normally. \commentary{% If the execution breaks with a label that prefixes the \WHILE{} statement, it does end execution of the loop, @@ -17120,35 +17497,43 @@ \subsection{Do} \LMLabel{do} \LMHash{}% -The do statement supports conditional iteration, where the condition is evaluated after the loop. +The do statement supports conditional iteration, +where the condition is evaluated after the loop. \begin{grammar} ::= \DO{} \WHILE{} `(' `)' `;' \end{grammar} \LMHash{}% -Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} proceeds as follows: +Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);} +proceeds as follows: \LMHash{}% The statement $\{s\}$ is executed. -If that execution continues with no label, or to a label (\ref{labels}) that prefixes the do statement (\ref{statementCompletion}), then the execution of $s$ is treated as if it had completed normally. +If that execution continues with no label, +or to a label (\ref{labels}) that prefixes the do statement +(\ref{statementCompletion}), +then the execution of $s$ is treated as if it had completed normally. \LMHash{}% Then, the expression $e$ is evaluated to an object $o$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o$ is not \code{bool}. -If $o$ is \FALSE{}, execution of the do statement completes normally (\ref{statementCompletion}). -If $o$ is \TRUE{}, then the do statement is re-executed. +If $o$ is \FALSE, execution of the do statement completes normally +(\ref{statementCompletion}). +If $o$ is \TRUE, then the do statement is re-executed. \LMHash{}% -It is a compile-time error if the static type of $e$ may not be assigned to \code{bool}. +It is a compile-time error if the static type of $e$ +may not be assigned to \code{bool}. \subsection{Switch} \LMLabel{switch} \LMHash{}% -The \Index{switch statement} supports dispatching control among a large number of cases. +The \Index{switch statement} supports dispatching control among +a large number of cases. \begin{grammar} ::= \gnewline{} @@ -17189,16 +17574,21 @@ \subsection{Switch} } \LMHash{}% -It is a compile-time error unless each expression $e_j, j \in 1 .. n$ is constant. -It is a compile-time error if the value of the expressions $e_j, j \in 1 .. n$ are not either: +It is a compile-time error unless each expression +$e_j, j \in 1 .. n$ is constant. +It is a compile-time error if the value of the expressions +$e_j, j \in 1 .. n$ are not either: \begin{itemize} \item instances of the same class $C$, for all $j \in 1 .. n$, or -\item instances of a class that implements \code{int}, for all $j \in 1 .. n$, or -\item instances of a class that implements \code{String}, for all $j \in 1 .. n$. +\item instances of a class that implements \code{int}, + for all $j \in 1 .. n$, or +\item instances of a class that implements \code{String}, + for all $j \in 1 .. n$. \end{itemize} \commentary{% -In other words, all the expressions in the cases evaluate to constants of the exact same user defined class or are of certain known types. +In other words, all the expressions in the cases evaluate to constants of +the exact same user defined class or are of certain known types. %% TODO(eernst): Update when we specify inference: const List xs = []; %% may be a counter-example: The value is a list that "knows" it is a %% `List` independently of the type annotation, but it wouldn't be a @@ -17252,7 +17642,8 @@ \subsection{Switch} proceeds as follows: \LMHash{}% -The statement \code{\VAR{} \id{} = $e$;} is evaluated, where \id{} is a fresh variable. +The statement \code{\VAR{} \id{} = $e$;} is evaluated, +where \id{} is a fresh variable. % This error can occur due to implicit casts and standard subsumption. %% TODO(eernst): But why couldn't $e$ be an instance of a subtype?! It is a dynamic error if the value of $e$ is @@ -17264,8 +17655,10 @@ \subsection{Switch} } \LMHash{}% -Next, the case clause \CASE{} $e_{1}$: $s_{1}$ is matched against \id, if $n > 0$. -Otherwise if there is a \DEFAULT{} clause, the case statements $s_{n+1}$ are executed (\ref{case-execute}). +Next, the case clause \CASE{} $e_{1}$: $s_{1}$ is matched against \id, +if $n > 0$. +Otherwise if there is a \DEFAULT{} clause, +the case statements $s_{n+1}$ are executed (\ref{case-execute}). \LMHash{}% Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement @@ -17285,8 +17678,12 @@ \subsection{Switch} The expression \code{$e_k$ == \id} is evaluated to an object $o$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o$ is not \code{bool}. -If $o$ is \FALSE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched against \id{} if $k < n$, and if $k = n$, then the \DEFAULT{} clause's statements are executed (\ref{case-execute}). -If $o$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h$ is non-empty. +If $o$ is \FALSE{} the following case, +\CASE{} $e_{k+1}: s_{k+1}$ is matched against \id{} if $k < n$, +and if $k = n$, then the \DEFAULT{} clause's statements are executed +(\ref{case-execute}). +If $o$ is \TRUE, let $h$ be the smallest number +such that $h \ge k$ and $s_h$ is non-empty. If no such $h$ exists, let $h = n + 1$. The case statements $s_h$ are then executed (\ref{case-execute}). @@ -17307,16 +17704,23 @@ \subsection{Switch} The expression \code{$e_k$ == \id} is evaluated to an object $o$. % This error can occur due to implicit casts and null. It is a dynamic error if the run-time type of $o$ is not \code{bool}. -If $o$ is \FALSE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched against \id{} if $k < n$. -If $o$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_h$ is non-empty. -If such a $h$ exists, the case statements $s_h$ are executed (\ref{case-execute}). -Otherwise the switch statement completes normally (\ref{statementCompletion}). +If $o$ is \FALSE{} the following case, +\CASE{} $e_{k+1}: s_{k+1}$ is matched against \id{} if $k < n$. +If $o$ is \TRUE, let $h$ be the smallest integer +such that $h \ge k$ and $s_h$ is non-empty. +If such a $h$ exists, the case statements $s_h$ are executed +(\ref{case-execute}). +Otherwise the switch statement completes normally +(\ref{statementCompletion}). \LMHash{}% -It is a compile-time error if the type of $e$ may not be assigned to the type of $e_k$. +It is a compile-time error if the type of $e$ +may not be assigned to the type of $e_k$. Let $s$ be the last statement of the statement sequence $s_k$. -If $s$ is a non-empty block statement, let $s$ instead be the last statement of the block statement. -It is a compile-time error if $s$ is not a \BREAK{}, \CONTINUE{}, \RETHROW{} or \RETURN{} statement +If $s$ is a non-empty block statement, let $s$ instead be +the last statement of the block statement. +It is a compile-time error if $s$ is not +a \BREAK, \CONTINUE, \RETHROW, or \RETURN{} statement, or an expression statement where the expression is a \THROW{} expression. \rationale{% @@ -17346,7 +17750,7 @@ \subsection{Switch} \begin{dartCode} \SWITCH{} (x) \{ - \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN{}; \} \FINALLY{} \{ $\ldots$ \RETURN{}; \} + \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN; \} \FINALLY{} \{ $\ldots$ \RETURN; \} \} \end{dartCode} @@ -17359,8 +17763,10 @@ \subsection{Switch} It is a static warning if all of the following conditions hold: \begin{itemize} \item The switch statement does not have a default clause. -\item The static type of $e$ is an enumerated type with elements $\id_1, \ldots, \id_n$. -\item The sets $\{e_1, \ldots, e_k\} $ and $\{\id_1, \ldots, \id_n\}$ are not the same. +\item The static type of $e$ is an enumerated + type with elements $\id_1, \ldots, \id_n$. +\item The sets $\{e_1, \ldots, e_k\} $ and $\{\id_1, \ldots, \id_n\}$ + are not the same. \end{itemize} \commentary{% @@ -17412,31 +17818,43 @@ \subsubsection{Switch case statements} to the end of the statement.% } -If execution of $\{s_h\}$ breaks with no label (\ref{statementCompletion}), then the execution of the switch statement completes normally. +If execution of $\{s_h\}$ breaks with no label (\ref{statementCompletion}), +then the execution of the switch statement completes normally. -If execution of $\{s_h\}$ continues to a label (\ref{statementCompletion}), and the label is $label_{ij}$, where $1 \le i \le n+1$ if the \SWITCH{} statement has a \DEFAULT{}, or $1 \le i \le n$ if there is no \DEFAULT{}, and where $1 \le j \le j_{i}$, then -let $h$ be the smallest number such that $h \ge i$ and $s_h$ is non-empty. -If no such $h$ exists, let $h = n + 1$ if the \SWITCH{} statement has a \DEFAULT{}, otherwise let $h = n$. +If execution of $\{s_h\}$ continues to a label +(\ref{statementCompletion}), +and the label is $label_{ij}$, +where $1 \le i \le n+1$ if the \SWITCH{} statement has a \DEFAULT, +or $1 \le i \le n$ if there is no \DEFAULT, +and where $1 \le j \le j_{i}$, +then let $h$ be the smallest number such that $h \ge i$ and $s_h$ is non-empty. +If no such $h$ exists, +let $h = n + 1$ if the \SWITCH{} statement has a \DEFAULT, +otherwise let $h = n$. The case statements $s_h$ are then executed (\ref{case-execute}). -If execution of $\{s_h\}$ completes in any other way, execution of the \SWITCH{} statement completes in the same way. +If execution of $\{s_h\}$ completes in any other way, +execution of the \SWITCH{} statement completes in the same way. \subsection{Rethrow} \LMLabel{rethrow} \LMHash{}% -The \Index{rethrow statement} is used to re-throw an exception and its associated stack trace. +The \Index{rethrow statement} is used to +re-throw an exception and its associated stack trace. \begin{grammar} ::= \RETHROW{} `;' \end{grammar} \LMHash{}% -Execution of a \code{\RETHROW{}} statement proceeds as follows: +Execution of a \code{\RETHROW} statement proceeds as follows: \LMHash{}% -Let $f$ be the immediately enclosing function, and let \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} be the immediately enclosing catch clause (\ref{try}). +Let $f$ be the immediately enclosing function, +and let \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$)} +be the immediately enclosing catch clause (\ref{try}). \rationale{% A \RETHROW{} statement always appears inside a \CATCH{} clause, @@ -17447,17 +17865,20 @@ \subsection{Rethrow} } \LMHash{}% -The \RETHROW{} statement throws (\ref{statementCompletion}) with $p_1$ as the exception object and $p_2$ as the stack trace. +The \RETHROW{} statement throws (\ref{statementCompletion}) +with $p_1$ as the exception object and $p_2$ as the stack trace. \LMHash{}% -It is a compile-time error if a \code{\RETHROW{}} statement is not enclosed within an \ON-\CATCH{} clause. +It is a compile-time error if a \code{\RETHROW} statement is not +enclosed within an \ON-\CATCH{} clause. \subsection{Try} \LMLabel{try} \LMHash{}% -The try statement supports the definition of exception handling code in a structured way. +The try statement supports the definition of exception handling code +in a structured way. \begin{grammar} ::= \TRY{} (+ ? | ) @@ -17474,7 +17895,11 @@ \subsection{Try} A try statement consists of a block statement, followed by at least one of: \begin{enumerate} \item -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 parameters, and a block statement. + 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 parameters, + and a block statement. \item A \FINALLY{} clause, which consists of a block statement. \end{enumerate} @@ -17487,23 +17912,45 @@ \subsection{Try} } \LMHash{}% -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{} $\{\}$}. +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{} $\{\}$}. \LMHash{}% -An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} where $p_2$ is a fresh identifier. +An \ON{}-\CATCH{} clause of the form +\code{\ON{} $T$ \CATCH{} ($p_1$) $s$} +is equivalent to an \ON{}-\CATCH{} clause +\code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} +where $p_2$ is a fresh identifier. \LMHash{}% -An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} where $p_1$ and $p_2$ are fresh identifiers. +An \ON{}-\CATCH{} clause of the form +\code{\ON{} $T$ $s$} +is equivalent to an \ON{}-\CATCH{} clause +\code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} +where $p_1$ and $p_2$ are fresh identifiers. \LMHash{}% -An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p$, $p_2$) $s$} where $p_2$ is a fresh identifier. +An \ON{}-\CATCH{} clause of the form +\code{\CATCH{} ($p$) $s$} +is equivalent to an \ON{}-\CATCH{} clause +\code{\ON{} \DYNAMIC{} \CATCH{} ($p$, $p_2$) $s$} +where $p_2$ is a fresh identifier. -An \ON{}-\CATCH{} clause of the form \code{\CATCH{} ($p_1$, $p_2$) $s$} is equivalent to an \ON{}-\CATCH{} clause \code{\ON{} \DYNAMIC{} \CATCH{} ($p_1$, $p_2$) $s$}. +An \ON{}-\CATCH{} clause of the form +\code{\CATCH{} ($p_1$, $p_2$) $s$} +is equivalent to an \ON{}-\CATCH{} clause +\code{\ON{} \DYNAMIC{} \CATCH{} ($p_1$, $p_2$) $s$}. \LMHash{}% -An \ON{}-\CATCH{} clause of the form \code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} introduces a new scope $CS$ in which final local variables specified by $p_1$ and $p_2$ are defined. +An \ON{}-\CATCH{} clause of the form +\code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$} +introduces a new scope $CS$ in which final local variables +specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$. -The static type of $p_1$ is $T$ and the static type of $p_2$ is \code{StackTrace}. +The static type of $p_1$ is $T$ +and the static type of $p_2$ is \code{StackTrace}. \LMHash{}% Execution of a \TRY{} statement $s$ of the form: @@ -17519,14 +17966,22 @@ \subsection{Try} \LMHash{}% First $b$ is executed. -If execution of $b$ throws (\ref{statementCompletion}) with exception object $e$ and stack trace $t$, then $e$ and $t$ are matched against the \ON{}-\CATCH{} clauses to yield a new completion (\ref{on-catch}). +If execution of $b$ throws (\ref{statementCompletion}) +with exception object $e$ and stack trace $t$, +then $e$ and $t$ are matched against the \ON{}-\CATCH{} clauses +to yield a new completion (\ref{on-catch}). -Then, even if execution of $b$ did not complete normally or matching against the \ON{}-\CATCH{} clauses did not complete normally, the $f$ block is executed. +Then, even if execution of $b$ did not complete normally +or matching against the \ON{}-\CATCH{} clauses did not complete normally, +the $f$ block is executed. If execution of $f$ does not complete normally, execution of the \TRY{} statement completes in the same way. -Otherwise if execution of $b$ threw (\ref{statementCompletion}), the \TRY{} statement completes in the same way as the matching against the \ON{}-\CATCH{} clauses. -Otherwise the \TRY{} statement completes in the same way as the execution of $b$. +Otherwise if execution of $b$ threw (\ref{statementCompletion}), +the \TRY{} statement completes in the same way as +the matching against the \ON{}-\CATCH{} clauses. +Otherwise the \TRY{} statement completes in the same way as +the execution of $b$. \LMHash{}% It is a compile-time error if $T_i$, $1 \le i \le n$ is a deferred type. @@ -17536,7 +17991,8 @@ \subsubsection{\ON{}-\CATCH{} clauses} \LMLabel{on-catch} \LMHash{}% -Matching an exception object $e$ and stack trace $t$ against a (potentially empty) sequence of \ON{}-\CATCH{} clauses of the form +Matching an exception object $e$ and stack trace $t$ against +a (potentially empty) sequence of \ON{}-\CATCH{} clauses of the form \begin{normativeDartCode} \ON{} $T_1$ \CATCH{} ($e_1$, $st_1$) \{ $s_1$ \} @@ -17546,17 +18002,25 @@ \subsubsection{\ON{}-\CATCH{} clauses} proceeds as follows: \LMHash{}% -If there are no \ON{}-\CATCH{} clauses ($n = 0$), matching throws the exception object $e$ and stack trace $t$ (\ref{statementCompletion}). +If there are no \ON{}-\CATCH{} clauses ($n = 0$), matching throws +the exception object $e$ and stack trace $t$ +(\ref{statementCompletion}). \LMHash{}% Otherwise the exception is matched against the first clause. \LMHash{}% -Otherwise, if the type of $e$ is a subtype of $T_1$, then the first clause matches, and then $e_1$ is bound to the exception object $e$ and $t_1$ is bound to the stack trace $t$, and $s_1$ is executed in this scope. +Otherwise, if the type of $e$ is a subtype of $T_1$, +then the first clause matches, +and then $e_1$ is bound to the exception object $e$ +and $t_1$ is bound to the stack trace $t$, +and $s_1$ is executed in this scope. The matching completes in the same way as this execution. \LMHash{}% -Otherwise, if the first clause did not match $e$, $e$ and $t$ are recursively matched against the remaining \ON{}-\CATCH{} clauses: +Otherwise, if the first clause did not match $e$, +$e$ and $t$ are recursively matched against +the remaining \ON{}-\CATCH{} clauses: \begin{normativeDartCode} \ON{} $T_2$ \CATCH{} ($e_2$, $t_2$) \{ $s_2$ \} @@ -17591,7 +18055,7 @@ \subsection{Return} (\ref{functions}). % % Returning without an object is only ok for "voidy" return types. -It is a compile-time error if $s$ is \code{\RETURN{};}, +It is a compile-time error if $s$ is \code{\RETURN;}, unless $T$ is \VOID, \DYNAMIC, or \code{Null}. % % Returning with an object in a void function @@ -17631,10 +18095,10 @@ \subsection{Return} (\ref{functions}). % % Returning without an object is only ok for async-"voidy" return types. -It is a compile-time error if $s$ is \code{\RETURN{};}, +It is a compile-time error if $s$ is \code{\RETURN;}, unless \flatten{T} (\ref{functionExpressions}) -is \VOID{}, \DYNAMIC{}, or \code{Null}. +is \VOID, \DYNAMIC, or \code{Null}. % \rationale{% An asynchronous non-generator always returns a future of some sort. @@ -17645,13 +18109,13 @@ \subsection{Return} % Returning with an object in an void async function only ok % when that value is async-"voidy". It is a compile-time error if $s$ is \code{\RETURN{} $e$;}, -\flatten{T} is \VOID{}, -and \flatten{S} is neither \VOID{}, \DYNAMIC{}, nor \code{Null}. +\flatten{T} is \VOID, +and \flatten{S} is neither \VOID, \DYNAMIC, nor \code{Null}. % % Returning async-void in a "non-async-voidy" function is an error. It is a compile-time error if $s$ is \code{\RETURN{} $e$;}, -\flatten{T} is neither \VOID{}, \DYNAMIC{}, nor \code{Null}, -and \flatten{S} is \VOID{}. +\flatten{T} is neither \VOID, \DYNAMIC, nor \code{Null}, +and \flatten{S} is \VOID. % % Otherwise, returning an un-deasync-assignable value is an error. It is a compile-time error if $s$ is \code{\RETURN{} $e$;}, @@ -17786,7 +18250,9 @@ \subsection{Labels} \LMHash{}% A \Index{label} is an identifier followed by a colon. A \Index{labeled statement} is a statement prefixed by a label $L$. -A \Index{labeled case clause} is a case clause within a switch statement (\ref{switch}) prefixed by a label $L$. +A \Index{labeled case clause} is a case clause within a switch statement +(\ref{switch}) +prefixed by a label $L$. \rationale{% The sole role of labels is to provide targets for @@ -17804,7 +18270,8 @@ \subsection{Labels} otherwise execution of $s$ completes in the same ways as the execution of $s_l$. \LMHash{}% -The namespace of labels is distinct from the one used for types, functions and variables. +The namespace of labels is distinct from the one used for +types, functions and variables. \LMHash{}% The scope of a label that labels a statement $s$ is $s$. @@ -17821,7 +18288,8 @@ \subsection{Break} \LMLabel{break} \LMHash{}% -The \Index{break statement} consists of the reserved word \BREAK{} and an optional label (\ref{labels}). +The \Index{break statement} consists of +the reserved word \BREAK{} and an optional label (\ref{labels}). \begin{grammar} ::= \BREAK{} ? `;' @@ -17832,22 +18300,26 @@ \subsection{Break} If $s_b$ is of the form \code{\BREAK{} $L$;}, then it is a compile-time error if $s_b$ is not enclosed in a labeled statement with the label $L$ within the innermost function in which $s_b$ occurs. -If $s_b$ is of the form \code{\BREAK{};}, +If $s_b$ is of the form \code{\BREAK;}, then it is a compile-time error if $s_b$ is not enclosed in an -\code{\AWAIT{} \FOR{}} (\ref{asynchronousFor-in}), +\code{\AWAIT{} \FOR} (\ref{asynchronousFor-in}), \DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch}) -or \WHILE{} (\ref{while}) statement within the innermost function in which $s_b$ occurs. +or \WHILE{} (\ref{while}) statement within +the innermost function in which $s_b$ occurs. \LMHash{}% -Execution of a \BREAK{} statement \code{\BREAK{} $L$;} breaks to the label $L$ (\ref{statementCompletion}). -Execution of a \BREAK{} statement \code{\BREAK{};} breaks without a label (\ref{statementCompletion}). +Execution of a \BREAK{} statement \code{\BREAK{} $L$;} breaks to the label $L$ +(\ref{statementCompletion}). +Execution of a \BREAK{} statement \code{\BREAK;} breaks without a label +(\ref{statementCompletion}). \subsection{Continue} \LMLabel{continue} \LMHash{}% -The \Index{continue statement} consists of the reserved word \CONTINUE{} and an optional label (\ref{labels}). +The \Index{continue statement} consists of the reserved word \CONTINUE{} +and an optional label (\ref{labels}). \begin{grammar} ::= \CONTINUE{} ? `;' @@ -17857,19 +18329,21 @@ \subsection{Continue} Let $s_c$ be a \CONTINUE{} statement. If $s_c$ is of the form \code{\CONTINUE{} $L$;}, then it is a compile-time error if $s_c$ is not enclosed in either an -\code{\AWAIT{} \FOR{}} (\ref{asynchronousFor-in}), +\code{\AWAIT{} \FOR} (\ref{asynchronousFor-in}), \DO{} (\ref{do}), \FOR{} (\ref{for}), or \WHILE{} (\ref{while}) statement labeled with $L$, or in a \SWITCH{} statement with a case clause labeled with $L$, within the innermost function in which $s_c$ occurs. -If $s_c$ is of the form \code{\CONTINUE{};} +If $s_c$ is of the form \code{\CONTINUE;} then it is a compile-time error if $s_c$ is not enclosed in an -\code{\AWAIT{} \FOR{}} (\ref{asynchronousFor-in}) +\code{\AWAIT{} \FOR} (\ref{asynchronousFor-in}) \DO{} (\ref{do}), \FOR{} (\ref{for}), or \WHILE{} (\ref{while}) statement within the innermost function in which $s_c$ occurs. \LMHash{}% -Execution of a \CONTINUE{} statement \code{\CONTINUE{} $L$;} continues to the label $L$ (\ref{statementCompletion}). -Execution of a \CONTINUE{} statement \code{\CONTINUE{};} continues without a label (\ref{statementCompletion}). +Execution of a \CONTINUE{} statement \code{\CONTINUE{} $L$;} continues +to the label $L$ (\ref{statementCompletion}). +Execution of a \CONTINUE{} statement \code{\CONTINUE;} continues +without a label (\ref{statementCompletion}). \subsection{Yield} @@ -17950,7 +18424,7 @@ \subsection{Yield} Therefore, we allow the enclosing function to be suspended when a new object is added to its associated stream. However, it is not essential (and in fact, can be quite costly) -to suspend the function on every \YIELD{}. +to suspend the function on every \YIELD. The implementation is free to decide how often to suspend the enclosing function. The only requirement is that consumers are not blocked indefinitely.% @@ -18048,7 +18522,7 @@ \subsection{Yield-Each} % This error can occur due to implicit casts. It is a dynamic type error if the class of $o$ is not a subtype of \code{Stream<$T_f$>}. -Otherwise + Otherwise \item The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused. @@ -18085,7 +18559,8 @@ \subsection{Assert} \LMLabel{assert} \LMHash{}% -An \Index{assert statement} is used to disrupt normal execution if a given boolean condition does not hold. +An \Index{assert statement} is used to disrupt normal execution +if a given boolean condition does not hold. \begin{grammar} ::= `;' @@ -18100,7 +18575,8 @@ \subsection{Assert} An assertion with a trailing comma is equivalent to one with that comma removed. \LMHash{}% -An assertion of the form \code{\ASSERT($e$)} is equivalent to an assertion of the form \code{\ASSERT($e$, \NULL{})}. +An assertion of the form \code{\ASSERT($e$)} is equivalent to +an assertion of the form \code{\ASSERT($e$, \NULL{})}. \LMHash{}% Execution of an assert statement executes the assertion as described below @@ -18122,12 +18598,17 @@ \subsection{Assert} Hence it is a compile-time error if that situation arises during evaluation of an assertion in a \CONST{} constructor invocation.% } -If $r$ is \TRUE{} then execution of the assert statement completes normally (\ref{statementCompletion}). +If $r$ is \TRUE{} then execution of the assert statement completes normally +(\ref{statementCompletion}). Otherwise, $e$ is evaluated to an object $m$ -and then the execution of the assert statement throws (\ref{statementCompletion}) an \code{AssertionError} containing $m$ and with a stack trace corresponding to the current execution state at the assertion. +and then the execution of the assert statement throws +(\ref{statementCompletion}) +an \code{AssertionError} containing $m$ and with +a stack trace corresponding to the current execution state at the assertion. \LMHash{}% -It is a compile-time error if the type of $c$ may not be assigned to \code{bool}. +It is a compile-time error if the type of $c$ +may not be assigned to \code{bool}. \rationale{% Why is this a statement, not a built in function call? @@ -18145,12 +18626,17 @@ \section{Libraries and Scripts} \LMLabel{librariesAndScripts} \LMHash{}% -A Dart program consists of one or more libraries, and may be built out of one or more \Index{compilation units}. +A Dart program consists of one or more libraries, +and may be built out of one or more \Index{compilation units}. A compilation unit may be a library or a part (\ref{parts}). \LMHash{}% -A library consists of (a possibly empty) set of imports, a set 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}). +A library consists of (a possibly empty) set of imports, a set 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 $L$. \begin{grammar} @@ -18317,7 +18803,7 @@ \subsection{Imports} \LMHash{}% An immediate import directive $I$ may optionally include -a \Index{prefix clause} of the form `\code{\AS{}\,\,\id}' used to prefix +a \Index{prefix clause} of the form `\code{\AS\,\,\id}' used to prefix names imported by $I$. In this case we say that \id{} is an \Index{import prefix}, or simply a \Index{prefix}. @@ -18332,7 +18818,7 @@ \subsection{Imports} It is a compile-time error if the prefix used in a deferred import is also used as the prefix of another import clause. It is a compile-time error if \id{} is an import prefix, -and the current library declares a top-level member with basename \id{}. +and the current library declares a top-level member with basename \id. \LMHash{}% An import directive $I$ may optionally include namespace combinator clauses @@ -18348,7 +18834,7 @@ \subsection{Imports} \code{\IMPORT{} 'dart:core';} unless the importing library explicitly imports \code{dart:core}. Any import of \code{dart:core}, -even if restricted via \SHOW{}, \HIDE{} or \AS{}, +even if restricted via \SHOW, \HIDE, or \AS, preempts the automatic import. \rationale{% @@ -18531,7 +19017,7 @@ \subsubsection{The Imported Namespace} \commentary{% \NamespaceName{\metavar{extensions}} provides a fresh name allowing implicit access to each extension exported by an imported library -and not removed by \HIDE{} or \SHOW{}, +and not removed by \HIDE{} or \SHOW, even the ones that cannot be accessed using their declared name, because of a name clash.% } @@ -18867,7 +19353,7 @@ \subsection{Namespace Combinators} in order to adjust namespaces (\ref{scoping}) and manage name clashes. -The supported namespace combinators are \SHOW{} and \HIDE{}. +The supported namespace combinators are \SHOW{} and \HIDE. \begin{grammar} ::= \SHOW{} | \HIDE{} @@ -19091,10 +19577,15 @@ \subsection{Parts} a sequence of top-level declarations. \LMHash{}% -Compiling a part directive of the form \code{\PART{} $s$;} causes the Dart system to attempt to compile the contents of the URI that is the value of $s$. -The top-level declarations at that URI are then compiled by the Dart compiler in the scope of the current library. -It is a compile-time error if the contents of the URI are not a valid part declaration. -It is a compile-time error if the referenced part declaration $p$ names a library other than the current library as the library to which $p$ belongs. +Compiling a part directive of the form \code{\PART{} $s$;} +causes the Dart system to attempt to compile the contents of +the URI that is the value of $s$. +The top-level declarations at that URI are then compiled by the Dart compiler +in the scope of the current library. +It is a compile-time error if the contents of the URI are not +a valid part declaration. +It is a compile-time error if the referenced part declaration $p$ names +a library other than the current library as the library to which $p$ belongs. \LMHash{}% It is a compile-time error if a library contains @@ -19202,36 +19693,48 @@ \subsection{URIs} \code{\metavar{uri} $\metavar{configurationUri}_1$ \ldots $\metavar{configurationUri}_n$} \IndexCustom{specifies a URI}{specify a URI} as follows: \begin{itemize} -\item{} Let $u$ be \metavar{uri}. -\item{} For each of the following configuration URIs of the form \code{\IF{} ($\metavar{test}_i$) $\metavar{uri}_i$}, in source order, do the following. -\begin{itemize} - \item{} If $\metavar{test}_i$ is \code{\metavar{ids}} with no \lit{==} clause, it is - equivalent to \code{\metavar{ids} == "true"}. - \item{} If $\metavar{test}_i$ is \code{\metavar{ids} == \metavar{string}}, - then create a string, \metavar{key}, from \metavar{ids} - by concatenating the identfiers and dots, - omitting any spaces between them that may occur in the source. - \item{} Look up \metavar{key} in the available - \Index{compilation environment}. - \commentary{% - The compilation environment is provided by the platform. - It maps some string keys to string values, - and can be accessed programmatically using the - \code{const String.fromEnvironment} constructor. - Tools may choose to only make some parts of the compilation environment - available for choosing configuration URIs.% - } - \item{} If the environment contains an entry for \metavar{key} and the - associated value is equal, as a constant string value, to the value of - the string literal \metavar{string}, - then let $u$ be $\metavar{uri}_i$ and stop iterating the configuration URIs. - \item{} Otherwise proceed to the next configuration URI. -\end{itemize} -\item{} The URI specified by $c$ is $u$. +\item + Let $u$ be \metavar{uri}. +\item + For each of the following configuration URIs of the form + \code{\IF{} ($\metavar{test}_i$) $\metavar{uri}_i$}, + in source order, do the following. + \begin{itemize} + \item + If $\metavar{test}_i$ is \code{\metavar{ids}} + with no \lit{==} clause, it is + equivalent to \code{\metavar{ids} == "true"}. + \item + If $\metavar{test}_i$ is \code{\metavar{ids} == \metavar{string}}, + then create a string, \metavar{key}, from \metavar{ids} + by concatenating the identfiers and dots, + omitting any spaces between them that may occur in the source. + \item + Look up \metavar{key} in the available + \Index{compilation environment}. + \commentary{% + The compilation environment is provided by the platform. + It maps some string keys to string values, + and can be accessed programmatically using the + \code{const String.fromEnvironment} constructor. + Tools may choose to only make some parts of the compilation environment + available for choosing configuration URIs.% + } + \item + If the environment contains an entry for \metavar{key} and the + associated value is equal, as a constant string value, to the value of + the string literal \metavar{string}, + then let $u$ be $\metavar{uri}_i$ and stop iterating the configuration URIs. + \item + Otherwise proceed to the next configuration URI. + \end{itemize} +\item + The URI specified by $c$ is $u$. \end{itemize} \LMHash{}% -This specification does not discuss the interpretation of URIs, with the following exceptions. +This specification does not discuss the interpretation of URIs, +with the following exceptions. \rationale{% The interpretation of URIs is mostly left to @@ -19244,10 +19747,12 @@ \subsection{URIs} } \LMHash{}% -A URI of the form \code{dart:$s$} is interpreted as a reference to a system library (\ref{imports}) $s$. +A URI of the form \code{dart:$s$} is interpreted as +a reference to a system library (\ref{imports}) $s$. \LMHash{}% -A URI of the form \code{package:$s$} is interpreted in an implementation specific manner. +A URI of the form \code{package:$s$} is interpreted in +an implementation specific manner. \rationale{% The intent is that, during development, Dart programmers can rely on @@ -19255,7 +19760,8 @@ \subsection{URIs} } \LMHash{}% -Otherwise, any relative URI is interpreted as relative to the location of the current library. +Otherwise, any relative URI is interpreted as relative to +the location of the current library. All further interpretation of URIs is implementation dependent. \commentary{% @@ -19295,20 +19801,21 @@ \subsection{Static Types} %% The precise rules are slightly different than the following sentence, but %% we should be able to make do with that for now. \LMHash{}% -In the grammar rules below, \synt{typeIdentifier} denotes an identifier which can be +In the grammar rules below, \synt{typeIdentifier} denotes +an identifier which can be the name of a type, that is, it denotes an \synt{IDENTIFIER} which is not a \synt{BUILT\_IN\_IDENTIFIER}. %% TODO(eernst): The following non-terminals are currently unused (they will %% be used when we transfer more grammar rules from Dart.g): %% and . They are used in the syntax for -%% \EXTENDS{}, \WITH{}, \IMPLEMENTS{} syntax and for mixin applications +%% \EXTENDS, \WITH, \IMPLEMENTS{} syntax and for mixin applications %% in Dart.g, and it seems likely that we will use them here as well. \commentary{% Non-terminals with names of the form \synt{\ldots{}NotFunction} derive terms which are types that are not function types. -Note that it \emph{does} derive the type \FUNCTION{}, +Note that it \emph{does} derive the type \FUNCTION, which is not itself a function type, but it is the least upper bound of all function types.% } @@ -19434,7 +19941,12 @@ \subsection{Static Types} However, all other compile-time errors must be issued under the assumption that all deferred libraries have successfully been loaded. -% Now, when passed to a generic, p.T also has to be treated as dynamic - otherwise we have to fail immediately. Where do we say that? And how does this fit with idea that as a type object it fails? Should we say that the accessor on p returns dynamic instead of failing? Do we distinguish its use in a constructor vs its use in an annotation? It's not that we evaluate type objects in constructor args - these cannot represent parameterized types. +% Now, when passed to a generic, p.T also has to be treated as dynamic - +% otherwise we have to fail immediately. Where do we say that? And how does +% this fit with idea that as a type object it fails? Should we say that the +% accessor on p returns dynamic instead of failing? Do we distinguish its use +% in a constructor vs its use in an annotation? It's not that we evaluate type +% objects in constructor args - these cannot represent parameterized types. \subsubsection{Type Promotion} @@ -19447,14 +19959,22 @@ \subsubsection{Type Promotion} may be promoted from the declared type, based on control flow. \LMHash{}% -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 are given in the relevant sections of the specification (\ref{logicalBooleanExpressions}, \ref{conditional} and \ref{if}). +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 are given in +the relevant sections of the specification +(\ref{logicalBooleanExpressions}, \ref{conditional} and \ref{if}). \LMHash{}% -Type promotion for a variable $v$ is allowed only when we can deduce that such promotion is valid based on an analysis of certain boolean expressions. -In such cases, 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 are mentioned explicitly in the relevant sections of this specification (\ref{typeTest} and \ref{logicalBooleanExpressions}). +Type promotion for a variable $v$ is allowed only when we can deduce that +such promotion is valid based on an analysis of certain boolean expressions. +In such cases, 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 are +mentioned explicitly in the relevant sections of this specification +(\ref{typeTest} and \ref{logicalBooleanExpressions}). \subsection{Dynamic Type System} @@ -20306,11 +20826,11 @@ \subsubsection{Being a subtype} This is the same as the forms of type that occur at top level in the conclusions of rule~\SrnPositionalFunctionType{} and -rule~\SrnNamedFunctionType{}.% +rule~\SrnNamedFunctionType.% } \LMHash{}% -In rules~\SrnCovariance{} and~\SrnSuperinterface{}, +In rules~\SrnCovariance{} and~\SrnSuperinterface, the first premise is a class declaration. This premise is satisfied in each of the following situations: @@ -20345,8 +20865,7 @@ \subsubsection{Being a subtype} (\ref{mixinApplication}), in which case $D$ in the rule is the synthetic class which specifies -the semantics of that mixin application -(\ref{mixinComposition}).% +the semantics of that mixin application.% } \commentary{% @@ -20409,8 +20928,8 @@ \subsubsection{Informal Subtype Rule Descriptions} so we will not repeat that. \Item{\SrnTop}{Top} Every type is a subtype of \code{Object}, - every type is a subtype of \DYNAMIC{}, - and every type is a subtype of \VOID{}. + every type is a subtype of \DYNAMIC, + and every type is a subtype of \VOID. Note that this implies that these types are equivalent according to the subtype relation. We denote these types, @@ -20456,13 +20975,15 @@ \subsubsection{Informal Subtype Rule Descriptions} (as specified in the current environment $\Gamma$) is a subtype of $T$. \Item{\SrnRightFunction}{Right Function} - Every function type is a subtype of the type \FUNCTION{}. + Every function type is a subtype of the type \FUNCTION. \Item{\SrnPositionalFunctionType}{Positional Function Type} A function type $F_1$ with positional optional parameters is a subtype of another function type $F_2$ with positional optional parameters - if the former has at most the same number of required parameters as the latter, - and the latter has at least the same total number of parameters as the former; + if the former has at most + the same number of required parameters as the latter, + and the latter has at least + the same total number of parameters as the former; the return type of $F_1$ is a subtype of that of $F_2$; and each parameter type of $F_1$ is a \emph{supertype} of the corresponding parameter type of $F_2$, if any. @@ -20506,7 +21027,7 @@ \subsubsection{Informal Subtype Rule Descriptions} the corresponding actual type argument of the latter. This rule may have $s = 0$ and cover a non-generic class as well, but that is redundant because this is already covered by - rule~\SrnReflexivity{}. + rule~\SrnReflexivity. \Item{\SrnSuperinterface}{Superinterface} Considering the case where $s = 0$ and $m = 0$ first, a parameterized type based on a non-generic class $C$ is a subtype of @@ -20521,8 +21042,8 @@ \subsubsection{Informal Subtype Rule Descriptions} that exists between two parameterized types based on $C$ and $D$. % %% TODO(eernst): Note that the specification of how to pass type arguments in - %% \ref{mixinApplication} is incorrect, and also that it will need to be rewritten - %% completely for the integration of the new mixin construct. + %% \ref{mixinApplication} is incorrect, and also that it will need to be + %% rewritten completely for the integration of the new mixin construct. The case where the superclass is a mixin application is covered via the equivalence with a declaration of a regular (possibly generic) superclass (\ref{mixinApplication}), @@ -20611,7 +21132,7 @@ \subsection{Function Types} \LMHash{}% A function object is always an instance of some class $C$ that implements the class \FUNCTION{} (\ref{functionType}), -and which has a method named \CALL{}, +and which has a method named \CALL, whose signature is the function type $C$ itself. \commentary{% Consequently, all function types are subtypes of \FUNCTION{} @@ -20619,20 +21140,20 @@ \subsection{Function Types} } -\subsection{Type \FUNCTION{}} +\subsection{Type \FUNCTION} \LMLabel{functionType} \LMHash{}% The built-in class \FUNCTION{} is a supertype of all function types (\ref{functionTypes}). -It is impossible to extend, implement, or mix in the class \FUNCTION{}. +It is impossible to extend, implement, or mix in the class \FUNCTION. \LMHash{}% If a class declaration or mixin application has \FUNCTION{} as superclass, it instead uses \code{Object} as superclass. \LMHash{}% -If a class or mixin declaration implements \FUNCTION{}, it has no effect. +If a class or mixin declaration implements \FUNCTION, it has no effect. It is as if the \FUNCTION was removed from the \code{implements} clause (and if it's the only implemented interface, the entire clause is removed). The resulting class or mixin interface @@ -20643,7 +21164,7 @@ \subsection{Type \FUNCTION{}} normal rules for mixin-application, but since the result of that mixin application is equivalent to a class with \code{implements Function}, and that clause has no effect, the resulting class also does not -implement \FUNCTION{}. \commentary{The \FUNCTION{} class declares no +implement \FUNCTION. \commentary{The \FUNCTION{} class declares no concrete instance members, so the mixin application creates a sub-class of the superclass with no new members and no new interfaces.} @@ -20657,7 +21178,7 @@ \subsection{Type \FUNCTION{}} } -\subsection{Type \DYNAMIC{}} +\subsection{Type \DYNAMIC} \LMLabel{typeDynamic} \LMHash{}% @@ -20669,7 +21190,7 @@ \subsection{Type \DYNAMIC{}} \commentary{% For instance, -when the receiver in an ordinary method invocation has type \DYNAMIC{}, +when the receiver in an ordinary method invocation has type \DYNAMIC, any method name can be invoked, with any number of type arguments or none, with any number of positional arguments, @@ -20683,10 +21204,10 @@ \subsection{Type \DYNAMIC{}} \LMHash{}% % Inference is assumed to have taken place, so the type was not inferred. If no static type annotation has been provided, -the type system considers declarations to have type \DYNAMIC{}. +the type system considers declarations to have type \DYNAMIC. %% TODO(eernst): Change when adding specification of instantiate-to-bound. If a generic type is used but type arguments are not provided, -the type arguments default to type \DYNAMIC{}. +the type arguments default to type \DYNAMIC. \commentary{% %% TODO(eernst): Amend when adding specification of instantiate-to-bound. @@ -20696,14 +21217,15 @@ \subsection{Type \DYNAMIC{}} the type $G$ is equivalent to \noindent -\code{$G$<$\DYNAMIC{}, \ldots,\ \DYNAMIC{}$>}.% +\code{$G$<$\DYNAMIC, \ldots,\ \DYNAMIC{}$>}.% } \LMHash{}% The built-in type declaration \code{dynamic}, which is declared in the library \code{dart:core}, denotes the \DYNAMIC{} type. -When the name \DYNAMIC{} exported by \code{dart:core} is evaluated as an expression, +When the name \DYNAMIC{} exported by \code{dart:core} is evaluated +as an expression, it evaluates to a \code{Type} object representing the \DYNAMIC{} type, even though \DYNAMIC{} is not a class. @@ -20722,26 +21244,32 @@ \subsection{Type \DYNAMIC{}} \begin{itemize} \item - Let $e$ be an expression of the form \code{$d$.\id}, which is not followed by an - argument part, where the static type of $d$ is \DYNAMIC, and \id{} is the name of a - getter declared in \code{Object}; if the return type of \code{Object.\id} is $T$ - then the static type of $e$ is $T$. + Let $e$ be an expression of the form \code{$d$.\id}, + which is not followed by an argument part, + where the static type of $d$ is \DYNAMIC, + and \id{} is the name of a getter declared in \code{Object}; + if the return type of \code{Object.\id} is $T$ then + the static type of $e$ is $T$. \commentary{% - For instance, \code{d.hashCode} has type \code{int} - and \code{d.runtimeType} has type \code{Type}.% + For instance, \code{d.hashCode} has type \code{int} + and \code{d.runtimeType} has type \code{Type}.% } \item - Let $e$ be an expression of the form \code{$d$.\id}, which is not followed by an - argument part, where the static type of $d$ is \DYNAMIC, and \id{} is the name of a - method declared in \code{Object} whose method signature has type $F$ - (\commentary{which is a function type}). The static type of $e$ is then $F$. + Let $e$ be an expression of the form \code{$d$.\id}, + which is not followed by an argument part, + where the static type of $d$ is \DYNAMIC, + and \id{} is the name of a method declared in \code{Object} + whose method signature has type $F$ + (\commentary{which is a function type}). + The static type of $e$ is then $F$. \commentary{% - For instance, \code{$d$.toString} has type \code{String \FUNCTION()}.% + For instance, \code{$d$.toString} has type \code{String \FUNCTION()}.% } \item - Let $e$ be an expression which is of the form \code{$d$.\id(\metavar{arguments})} + Let $e$ be an expression which is of the form + \code{$d$.\id(\metavar{arguments})} or the form \code{$d$.\id<\metavar{typeArguments}>(\metavar{arguments})}, where the static type of $d$ is \DYNAMIC, \id{} is the name of a getter declared in \code{Object} with return type $F$, @@ -20768,11 +21296,13 @@ \subsection{Type \DYNAMIC{}} an actual argument list derived from \synt{arguments}, and \id{} is the name of a method declared in \code{Object} whose method signature has type $F$. - If the number of positional actual arguments in \metavar{arguments} is less than the - number of required positional arguments of $F$ or greater than the number - of positional arguments in $F$, or if \metavar{arguments} includes any named - arguments with a name that is not declared in $F$, the type of $e$ is - \DYNAMIC. Otherwise, the type of $e$ is the return type in $F$. + If the number of positional actual arguments in \metavar{arguments} + is less than the number of required positional arguments of $F$ + or greater than the number of positional arguments in $F$, + or if \metavar{arguments} includes any named arguments + with a name that is not declared in $F$, + the type of $e$ is \DYNAMIC. + Otherwise, the type of $e$ is the return type in $F$. \commentary{% So \code{$d$.toString(bazzle:\,42)} has type \DYNAMIC{} whereas \code{$d$.toString()} has type \code{String}. @@ -20783,20 +21313,21 @@ \subsection{Type \DYNAMIC{}} \item Let $e$ be an expression of the form \code{$d$.\id<\metavar{typeArguments}>(\metavar{arguments})} where - the static type of $d$ is \DYNAMIC, \metavar{typeArguments} is a list of actual + the static type of $d$ is \DYNAMIC, + \metavar{typeArguments} is a list of actual type arguments derived from \synt{typeArguments}, and \metavar{arguments} is an actual argument list derived from \synt{arguments}. It is a compile-time error if \id{} is the name of a non-generic method declared in \code{Object}. \commentary{% - No generic methods are declared in \code{Object}. - Hence, we do not specify that there must be - the statically required number of actual type arguments, and - they must satisfy the bounds. - That would otherwise be the consistent approach, - because the invocation is guaranteed to fail when any of those - requirements are violated, - but generalizations of this mechanism would need to include such rules.% + No generic methods are declared in \code{Object}. + Hence, we do not specify that there must be + the statically required number of actual type arguments, and + they must satisfy the bounds. + That would otherwise be the consistent approach, + because the invocation is guaranteed to fail when any of those + requirements are violated, + but generalizations of this mechanism would need to include such rules.% } \item @@ -20808,7 +21339,7 @@ \subsection{Type \DYNAMIC{}} a getter or method invocation that corresponds to one of the cases above, the corresponding static analysis and compile-time errors apply. \commentary{% - For instance, \code{$d$..foobar(16)..hashCode()} is an error.% + For instance, \code{$d$..foobar(16)..hashCode()} is an error.% } \end{itemize} @@ -20819,7 +21350,8 @@ \subsection{Type \DYNAMIC{}} even though they could also be considered "invocations", and subexpressions are checked separately so any given actual argument could be a compile-time error. -But almost any given argument list shape could be handled via \code{noSuchMethod}, +But almost any given argument list shape could be handled via +\code{noSuchMethod}, and an argument of any type could be accepted because any formal parameter in an overriding declaration could have its type annotation contravariantly changed to \code{Object}. @@ -21046,7 +21578,7 @@ \subsection{Type Void} \item In an expression of the form \code{$e_1$\,=\,$e_2$} where $e_1$ is an \synt{assignableExpression} - denoting a variable or formal parameter of type \VOID{}, + denoting a variable or formal parameter of type \VOID, $e_2$ may have type \VOID. \rationale{% Usages of that variable or formal parameter @@ -21081,7 +21613,7 @@ \subsection{Type Void} \LMHash{}% Finally, we need to address situations involving implicit usage of -an object whose static type can be \VOID{}. +an object whose static type can be \VOID. % It is a compile-time error for a for-in statement to have an iterator expression of type $T$ such that \code{Iterator<\VOID{}>} @@ -21177,13 +21709,13 @@ \subsubsection{Void Soundness} a formal parameter with the same type. % However, no special treatment is given when an expression has a type -which is or contains a type variable whose value could be \VOID{}, +which is or contains a type variable whose value could be \VOID, so we are allowed to return \code{x} in the body of \code{f}, even though this means that we indirectly get access to the value -of an expression of type \VOID{}, under the static type \code{Object}. +of an expression of type \VOID, under the static type \code{Object}. At (2), we indirectly obtain access to the value of -the variable \code{x} with type \VOID{}, +the variable \code{x} with type \VOID, because we use an assignment to get access to the instance of \code{B} which was created with type argument \VOID{} under the type \code{A}. @@ -21195,7 +21727,7 @@ \subsubsection{Void Soundness} the variable \code{x} with type \VOID{} under the static type \code{Object}, because the statically known method signature of \code{foo} -has parameter type \VOID{}, +has parameter type \VOID, but the actual implementation of \code{foo} which is invoked is an override whose parameter type is \code{Object}, which is allowed because \code{Object} and \VOID{} are both top types.% @@ -21216,10 +21748,10 @@ \subsubsection{Void Soundness} It would certainly have been possible to define sound rules, such that the value of an expression of type \VOID{} would be guaranteed to be discarded after some number of transfers -from one variable or parameter to the next one, all with type \VOID{}, +from one variable or parameter to the next one, all with type \VOID, explicitly, or as the value of a type parameter. In particular, we could require that method overrides should -never override return type \code{Object} by return type \VOID{}, +never override return type \code{Object} by return type \VOID, or parameter types in the opposite direction; parameterized types with type argument \VOID{} could not be assigned to variables where the corresponding type argument is anything other than @@ -21227,7 +21759,7 @@ \subsubsection{Void Soundness} But this would be quite impractical. In particular, the need to either prevent a large number of type variables -from ever having the value \VOID{}, +from ever having the value \VOID, or preventing certain usages of values whose type is such a type variable, or whose type contains such a type variable, that would be severely constraining on a very large part of all Dart code. @@ -21244,15 +21776,18 @@ \subsection{Parameterized Types} % TODO(eernst): We may want to add a new concept for the application of a % generic function to actual type arguments (maybe it's an extra kind of -% 'parameterized type', but it differs from the generic class case because +% `parameterized type', but it differs from the generic class case because % we _can_ have dynamic invocations of a generic function). But this does % not arise as a stand-alone entity before we introduce generic tear-offs % (\code{var f = foo;}), or if we allow it to arise implicitly based % on inference. That new concept should probably be added to this section. \LMHash{}% -A \emph{parameterized type} is a syntactic construct where the name of a generic type declaration is applied to a list of actual type arguments. -A \emph{generic instantiation} is the operation where a generic type is applied to actual type arguments. +A \emph{parameterized type} is a syntactic construct +where the name of a generic type declaration is applied to +a list of actual type arguments. +A \emph{generic instantiation} is the operation where +a generic type is applied to actual type arguments. \commentary{% So a parameterized type is the syntactic concept that corresponds to @@ -21265,7 +21800,8 @@ \subsection{Parameterized Types} \LMHash{}% It is a compile-time error if $G$ is not a generic type, -or $G$ is a generic type, but the number of formal type parameters in the declaration of $G$ is not $n$. +or $G$ is a generic type, +but the number of formal type parameters in the declaration of $G$ is not $n$. Otherwise, let $X_1, \ldots, X_n$ be the formal type parameters of $G$, and let @@ -21283,7 +21819,8 @@ \subsection{Parameterized Types} \LMHash{}% $T$ is evaluated as follows. Let $t_i$ be the result of evaluating $S_i$, for $i \in 1 .. n$. -$T$ then evaluates to the generic instantiation where $G$ is applied to $t_1, \ldots, t_n$. +$T$ then evaluates to the generic instantiation +where $G$ is applied to $t_1, \ldots, t_n$. \LMHash{}% Let $T$ be a parameterized type of the form @@ -21296,18 +21833,19 @@ \subsection{Parameterized Types} $[A_1/X_1, \ldots, A_n/X_n]S$, where $X_1, \ldots, X_n$ are the formal type parameters of $G$. -%% TODO(eernst): This is the location where we can specify that each of the type arguments -%% of the receiver type \code{$G$<$A_1, \ldots,\ A_n$>} must be replaced by the bottom type -%% (`Null`, for now) in locations of the member type where it occurs contravariantly. For -%% instance, `c.f` should have static type `void Function(Null)` when `c` has static type -%% `C` for any `T`, and we have `class C { void Function(X) f; }`. +%% TODO(eernst): This is the location where we can specify that each of the +%% type arguments of the receiver type \code{$G$<$A_1, \ldots,\ A_n$>} must be +%% replaced by the bottom type (`Null`, for now) in locations of the member +%% type where it occurs contravariantly. For instance, `c.f` should have +%% static type `void Function(Null)` when `c` has static type `C` for any +%% `T`, and we have `class C { void Function(X) f; }`. \subsubsection{Actual Types} \LMLabel{actualTypes} % NOTE(eernst): The actual type arguments in this section are dynamic entities, -% not syntax (the concept of an 'actual type' and an 'actual bound' is used to +% not syntax (the concept of an `actual type' and an 'actual bound' is used to % specify the dynamic semantics, including dynamic errors). So we use $t_i$ % to denote these type arguments, just like all those locations where the % concept is used, rather than $A_i$ which is frequently used to denote the @@ -21371,17 +21909,18 @@ \subsubsection{Least Upper Bounds} we define $S_n = \{T | T \in S \wedge depth(T) = n\}$ for any finite $n$ where $depth(T)$ is the number of steps in the longest inheritance path from $T$ to \code{Object}. -%TODO(lrn): Specify that "inheritance path" is a path in the superinterface graph. +%TODO(lrn): Specify: "inheritance path" is a path in the superinterface graph. Let $q$ be the largest number such that $S_q$ has cardinality one, which must exist because $S_0$ is $\{\code{Object}\}$. The least upper bound of $I$ and $J$ is the sole element of $S_q$. \LMHash{}% -The least upper bound of \DYNAMIC{} and any type $T$ is \DYNAMIC{}. -The least upper bound of \VOID{} and any type $T \ne \DYNAMIC{}$ is \VOID{}. +The least upper bound of \DYNAMIC{} and any type $T$ is \DYNAMIC. +The least upper bound of \VOID{} and any type $T \ne \DYNAMIC{}$ is \VOID. The least upper bound of $\bot$ and any type $T$ is $T$. Let $U$ be a type variable with upper bound $B$. -The least upper bound of $U$ and a type $T \ne \bot$ is the least upper bound of $B$ and $T$. +The least upper bound of $U$ and a type $T \ne \bot$ is +the least upper bound of $B$ and $T$. \LMHash{}% The least upper bound operation is commutative and idempotent, @@ -21393,42 +21932,51 @@ \subsubsection{Least Upper Bounds} %% (\FunctionTypePositionalStd{} etc.); these updates are made by CL 84908. \LMHash{}% -The least upper bound of a function type and an interface type $T$ is the least upper bound of \FUNCTION{} and $T$. +The least upper bound of a function type and an interface type $T$ is +the least upper bound of \FUNCTION{} and $T$. Let $F$ and $G$ be function types. If $F$ and $G$ differ in their number of required parameters, -then the least upper bound of $F$ and $G$ is \FUNCTION{}. +then the least upper bound of $F$ and $G$ is \FUNCTION. Otherwise: \begin{itemize} \item If +\noindent \code{$F = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($T_1, \ldots,\ T_r,\ $[$T_{r+1}, \ldots,\ T_n$]) $ \rightarrow T_0$} and +\noindent \code{$G = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($S_1, \ldots,\ S_r,\ $[$S_{r+1}, \ldots,\ S_k$]) $ \rightarrow S_0$} \noindent where $k \le n$ then the least upper bound of $F$ and $G$ is +\noindent \code{<$X_1\ B_1, \ldots,\ X_s\ B_s$>($L_1, \ldots,\ L_r,\ $[$L_{r+1}, \ldots,\ L_k$]) $ \rightarrow L_0$} \noindent where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0 .. k$. \item If +\noindent \code{$F = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($T_1, \ldots,\ T_r,\ $[$T_{r+1}, \ldots,\ T_n$]) $ \rightarrow T_0$}, +\noindent \code{$G = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($S_1, \ldots,\ S_r,\ $\{ \ldots{} \}) $ \rightarrow S_0$} \noindent then the least upper bound of $F$ and $G$ is +\noindent \code{<$X_1\ B_1, \ldots,\ X_s\ B_s$>($L_1, \ldots,\ L_r$) $ \rightarrow L_0$} \noindent where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0 .. r$. \item If +\noindent \code{$F = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($T_1, \ldots,\ T_r,\ $\{$T_{r+1}\ p_{r+1}, \ldots,\ T_f\ p_f$\}) $ \rightarrow T_0$}, +\noindent \code{$G = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($S_1, \ldots,\ S_r,\ $\{$S_{r+1}\ q_{r+1}, \ldots,\ S_g\ q_g$\}) $ \rightarrow S_0$} then let @@ -21437,6 +21985,7 @@ \subsubsection{Least Upper Bounds} $G, j \in m .. n$. Then the least upper bound of $F$ and $G$ is +\noindent \code{<$X_1\ B_1, \ldots,\ X_s\ B_s$>($L_1, \ldots,\ L_r,\ $\{$X_m\ x_m, \ldots,\ X_n\ x_n$\}) $ \rightarrow L_0$} where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0 .. r$ @@ -21457,8 +22006,10 @@ \subsection{Lexical Rules} \LMHash{}% Dart source text is represented as a sequence of Unicode code points. -This sequence 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 longest possible token is recognized. +This sequence 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 longest possible token is recognized. \subsubsection{Reserved Words} @@ -21507,11 +22058,16 @@ \subsubsection{Comments} \LMHash{}% Dart supports both single-line and multi-line comments. A \Index{single line comment} 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. +Everything between \code{//} and the end of line +must be ignored by the Dart compiler +unless the comment is a documentation comment. \LMHash{}% -A \Index{multi-line comment} begins with the token \code{/*} and ends with the token \code{*/}. -Everything between \code{/}* and \code{*}/ must be ignored by the Dart compiler unless the comment is a documentation comment. +A \Index{multi-line comment} begins with the token \code{/*} +and ends with the token \code{*/}. +Everything between \code{/}* and \code{*}/ +must be ignored by the Dart compiler +unless the comment is a documentation comment. Comments may nest. \LMHash{}% @@ -21562,7 +22118,7 @@ \subsection{Operator Precedence} \hline Bitwise Or & \code{|} & Left & 9\\ \hline -Relational & \code{<}, \code{>}, \code{<=}, \code{>=}, \AS{}, \IS{}, \code{\IS{}!} & None & 8\\ +Relational & \code{<}, \code{>}, \code{<=}, \code{>=}, \AS, \IS, \code{\IS{}!} & None & 8\\ \hline Equality & \code{==}, \code{!=} & None & 7\\ \hline @@ -21645,8 +22201,8 @@ \section*{Appendix: Algorithmic Subtyping} } \LMHash{}% -The only rule which is modified is number~\SrnReflexivity{}, -which is modified to \AppSrnReflexivity{}. +The only rule which is modified is number~\SrnReflexivity, +which is modified to \AppSrnReflexivity. This only changes the applicability of the rule: This rule is only used for types which are not atomic. An \IndexCustom{atomic type}{type!atomic} @@ -21657,7 +22213,7 @@ \section*{Appendix: Algorithmic Subtyping} \commentary{% In other words, rule \AppSrnReflexivity{} is used for -special types like \DYNAMIC{}, \VOID{}, and \FUNCTION{}, +special types like \DYNAMIC, \VOID, and \FUNCTION, and it is used for non-generic classes, but it is not used for any type where it is an operation that takes more than one comparison to detect whether @@ -21716,7 +22272,8 @@ \section*{Appendix: Algorithmic Subtyping} Next, rules \SrnPositionalFunctionType--\SrnCovariance{} require work proportional to the size of $S$ and $T$, due to the number of premises that must be checked. -Finally, rule~\SrnSuperinterface{} requires work proportional to the size of $S$, +Finally, rule~\SrnSuperinterface{} requires work +proportional to the size of $S$, and it may also incur the cost of searching up to the entire set of direct and indirect superinterfaces of the candidate subtype $S$, until the corresponding premise for one of them is shown to hold, @@ -21729,9 +22286,9 @@ \section*{Appendix: Algorithmic Subtyping} if $T$ is a type variable or a function type. For several other forms of type, e.g., a promoted type variable, -\code{Object}, \DYNAMIC{}, \VOID{}, -\code{FutureOr<$T$>} for any $T$, or \FUNCTION{}, -it is known that it will never occur as $T$ for rule~\SrnSuperinterface{}, +\code{Object}, \DYNAMIC, \VOID, +\code{FutureOr<$T$>} for any $T$, or \FUNCTION, +it is known that it will never occur as $T$ for rule~\SrnSuperinterface, which means that this seemingly expensive step can be confined to some extent.% } @@ -21946,6 +22503,6 @@ \subsubsection{New} would be marked as a dependency on 'sec:new', individual \item{}s in itemized lists addressable. Each \LM.. command must occur on a separate line. \LMHash{} must occur immediately before the associated paragraph, and \LMLabel must occur immediately -after the associated \section{}, \subsection{} etc. +after the associated \section, \subsection{} etc. ----------------------------------------------------------------------